Example code of Vue3 encapsulated magnifying glass component

Example code of Vue3 encapsulated magnifying glass component

Component Infrastructure

There 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 function

step:

  • First prepare the large image container and the mask container
  • Then use the useMouseInElement method of @vueuse/core to get the element-based offset
  • Calculate the mask container position and the large container background position and expose the data to the template for use

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 vueuse

npm i @vueuse/core@5.3.0

Currently version 5.3.0 is relatively stable

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>

Summarize

This 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:
  • Vue realizes the product magnifying glass effect
  • Vue3 realizes the image magnifying glass effect
  • Vue implements the magnifying glass function of the product details page
  • Vue implements the magnifying glass effect of tab switching
  • Vue implements a simple magnifying glass effect
  • Vue implements a search box with a magnifying glass
  • Vue3.0 handwriting magnifying glass effect
  • Vue implements magnifying glass effect
  • A handwritten vue magnifying glass effect
  • Vue3 encapsulates the magnifying glass effect component of Jingdong product details page

<<:  MySQL master-slave replication configuration process

>>:  How to use sed command to efficiently delete specific lines of a file

Recommend

How to use docker to deploy Django technology stack project

With the popularity and maturity of Docker, it ha...

Implementing Markdown rendering in Vue single-page application

When rendering Markdown before, I used the previe...

Detailed summary of MySQL and connection-related timeouts

MySQL and connection related timeouts Preface: To...

How to use the Clipboard API in JS

Table of contents 1. Document.execCommand() metho...

Detailed explanation of the execution principle of MySQL kill command

Table of contents Kill instruction execution prin...

Vue implements Tab tab switching

This article example shares the specific code of ...

Four practical tips for JavaScript string operations

Table of contents Preface 1. Split a string 2. JS...

Binary Search Tree Algorithm Tutorial for JavaScript Beginners

Table of contents What is a Binary Search Tree (B...

CentOS7 installation GUI interface and remote connection implementation

Use the browser (webdriver)-based selenium techno...

Detailed explanation of Object.create instance usage in js

1. Create a new object using the Object.create() ...

Tomcat parses XML and creates objects through reflection

The following example code introduces the princip...

Build a file management system step by step with nginx+FastDFS

Table of contents 1. Introduction to FastDFS 1. I...

Free tool to verify that HTML, CSS and RSS feeds are correct

One trick for dealing with this type of error is t...

How to dynamically modify container port mapping in Docker

Preface: Docker port mapping is often done by map...