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/[email protected]
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
Suddenly when I logged into MySQL, it said that a...
This article shares the specific code of JavaScri...
Folding display multi-line text component Fold an...
1. Top-level usage 1. Install cnpm npm i -g cnpm ...
The Swap partition of the Linux system, that is, ...
Preface Most of our MySQL online environments use...
<br />In the previous article, I introduced ...
Preface What is state We all say that React is a ...
Docker is an open source engine that makes it eas...
1. Node server setup + database connection The op...
Problem Description There is a type of query call...
First, we need a server with Docker installed. (I...
Using the CSS float property correctly can become...
The CentOS Project, a 100% compatible rebuild of ...
Table of contents 1. ACID Characteristics Transac...