Component InfrastructureThere is a complete code at the end that can be copied and used directly Purpose: Encapsulate the image preview component to achieve the mouse hover switching effect Landing code: <template> <div class="goods-image"> <div class="middle"> <img :src="images[currIndex]" alt=""> </div> <ul class="small"> <li v-for="(img,i) in images" :key="img" :class="{active:i===currIndex}"> <img @mouseenter="currIndex=i" :src="img" alt=""> </li> </ul> </div> </template> <script> import { ref } from 'vue' export default { name: 'GoodsImage', props: { images: type: Array, default: () => [] } }, setup (props) { const currIndex = ref(0) return { currIndex } } } </script> <style scoped lang="less"> .goods-image { width: 480px; height: 400px; position: relative; display: flex; .middle { width: 400px; height: 400px; background: #f5f5f5; } .small { width: 80px; li { width: 68px; height: 68px; margin-left: 12px; margin-bottom: 15px; cursor: pointer; &:hover,&.active { border: 2px solid @xtxColor; } } } } </style> Image Magnifier Purpose: To realize the image magnifying glass functionstep:
Landing code: <template> <div class="goods-image"> + // Achieve the large image layout effect on the right (enlarge the background image 4 times) + <div class="large" :style="[{backgroundImage:`url(${images[currIndex]})`}]"></div> <div class="middle"> <img :src="images[currIndex]" alt=""> + // Prepare the mask container to be moved + <div class="layer"></div> </div> <ul class="small"> <li v-for="(img,i) in images" :key="img" :class="{active:i===currIndex}"> <img @mouseenter="currIndex=i" :src="img" alt=""> </li> </ul> </div> </template> <script> import { ref } from 'vue' export default { name: 'GoodsImage', props: { images: type: Array, default: () => [] } }, setup (props) { const currIndex = ref(0) return { currIndex } } } </script> <style scoped lang="less"> .goods-image { width: 480px; height: 400px; position: relative; display: flex; + z-index: 500; + // Right large image style+ .large { + position: absolute; + top: 0; + left: 412px; + width: 400px; + height: 400px; + box-shadow: 0 0 10px rgba(0,0,0,0.1); + background-repeat: no-repeat; + background-size: 800px 800px; + background-color: #f8f8f8; + } .middle { width: 400px; height: 400px; background: #f5f5f5; + position: relative; + cursor: move; + // Mask style+ .layer { + width: 200px; + height: 200px; + background: rgba(0,0,0,.2); + left: 0; + top: 0; + position: absolute; + } } .small { width: 80px; li { width: 68px; height: 68px; margin-left: 12px; margin-bottom: 15px; cursor: pointer; &:hover,&.active { border: 2px solid @xtxColor; } } } } </style> Install vueusenpm i @vueuse/core@5.3.0
Basic usage of the listening method provided by vueuse to enter the specified range import { useMouseInElement } from '@vueuse/core' const { elementX, elementY, isOutside } = useMouseInElement(target) The method parameter target represents the monitored DOM object; the return values elementX and elementY represent the position information of the upper left corner of the monitored DOM, left and top; isOutside represents whether it is within the range of the DOM, true means it is outside the range. false means within the range. Functionality<div v-if="isShow" class="large" :style="[{ backgroundImage: `url(${images[currIndex]})` }, bgPosition]"></div> <div class="middle" ref="target"> <img :src="images[currIndex]" alt="" /> <div class="layer" v-if="isShow" :style="[position]"></div> </div> setup () { // The monitored area const target = ref(null) // Control the display and hiding of the mask layer and preview image const isShow = ref(false) // Define the coordinates of the mask const position = reactive({ left: 0, top: 0 }) // Coordinates of the preview image on the right const bgPosition = reactive({ backgroundPositionX: 0, backgroundPositionY: 0 }) return { position, bgPosition, target, isShow } } const { elementX, elementY, isOutside } = useMouseInElement(target) // Listen for value changes based on the listener watch([elementX, elementY, isOutside], () => { // Control display and hiding through flags isShow.value = !isOutside.value if (isOutside.value) return // X-axis coordinate range control if (elementX.value < 100) { // Left side position.left = 0 } else if (elementX.value > 300) { // Right side position.left = 200 } else { // Middle position.left = elementX.value - 100 } // Y direction coordinate range control if (elementY.value < 100) { position.top = 0 } else if (elementY.value > 300) { position.top = 200 } else { position.top = elementY.value - 100 } // Calculate the moving distance of the preview image bgPosition.backgroundPositionX = -position.left * 2 + 'px' bgPosition.backgroundPositionY = -position.top * 2 + 'px' // Calculate the position of the mask layer position.left = position.left + 'px' position.top = position.top + 'px' }) Complete code<template> <div class="goods-image"> <div v-if="isShow" class="large" :style="[{ backgroundImage: `url(${images[currIndex]})` }, bgPosition]"></div> <div class="middle" ref="target"> <img :src="images[currIndex]" alt="" /> <div class="layer" v-if="isShow" :style="[position]"></div> </div> <ul class="small"> <li v-for="(img, i) in images" :key="img" :class="{ active: i === currIndex }"> <img @mouseenter="currIndex = i" :src="img" alt="" /> </li> </ul> </div> </template> <script> import { ref, watch, reactive } from 'vue' import { useMouseInElement } from '@vueuse/core' export default { name: 'GoodsImage', props: { images: type: Array, default: () => [] } }, setup (props) { const currIndex = ref(0) const target = ref(null) const isShow = ref(false) const position = reactive({ left: 0, top: 0 }) const bgPosition = reactive({ backgroundPositionX: 0, backgroundPositionY: 0 }) const { elementX, elementY, isOutside } = useMouseInElement(target) watch([elementX, elementY, isOutside], () => { isShow.value = !isOutside.value if (isOutside.value) return if (elementX.value <= 100) { position.left = 0 } else if (elementX.value >= 300) { position.left = 200 } else { position.left = elementX.value - 100 } if (elementY.value <= 100) { position.top = 0 } else if (elementY.value >= 300) { position.top = 200 } else { position.top = elementY.value - 100 } bgPosition.backgroundPositionX = -position.left * 2 + 'px' bgPosition.backgroundPositionY = -position.top * 2 + 'px' position.left += 'px' position.top += 'px' }) return { currIndex, target, isShow, position, bgPosition } } } </script> <style scoped lang="less"> .goods-image { width: 480px; height: 400px; position: relative; display: flex; z-index: 500; .large { position: absolute; top: 0; left: 412px; width: 400px; height: 400px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); background-repeat: no-repeat; background-size: 800px 800px; background-color: #f8f8f8; } .middle { width: 400px; height: 400px; background: #f5f5f5; position: relative; cursor: move; .layer { width: 200px; height: 200px; background: rgba(0,0,0,.2); left: 0; top: 0; position: absolute; } } .small { width: 80px; li { width: 68px; height: 68px; margin-left: 12px; margin-bottom: 15px; cursor: pointer; &:hover, &.active { border: 2px solid @xtxColor; } } } } </style> SummarizeThis is the end of this article about the vue3 encapsulated magnifying glass component. For more relevant vue3 encapsulated magnifying glass component content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: MySQL master-slave replication configuration process
>>: How to use sed command to efficiently delete specific lines of a file
With the popularity and maturity of Docker, it ha...
When rendering Markdown before, I used the previe...
MySQL and connection related timeouts Preface: To...
Table of contents 1. Document.execCommand() metho...
Table of contents Kill instruction execution prin...
This article example shares the specific code of ...
Table of contents Preface 1. Split a string 2. JS...
Table of contents What is a Binary Search Tree (B...
Use the browser (webdriver)-based selenium techno...
1. Create a new object using the Object.create() ...
The following example code introduces the princip...
Table of contents 1. Introduction to FastDFS 1. I...
One trick for dealing with this type of error is t...
-9999 px image replacement technology has been pop...
Preface: Docker port mapping is often done by map...