preface

When shopping website, we must have seen the mouse on goods, there will be a magnified effect. Today we will encapsulate a magnifying glass effect of the global component, let’s take a look


First, the meaning of encapsulation

  • From a technical perspective

    • Encapsulation as a global component through the VUE plug-in, the whole project can be used in other locations, and easy to use
    • The idea of modular development is that one module implements one function
  • User perspective

    • Can lead to a better browsing experience
    • You can see the details of the product

Two, how to package?

1. Prepare

The @vueuse/core useMouseInElement method is needed, so open the terminal in the project root directory and run the following command

Here the installation of the specified version, you small partners as required to choose

NPM install @ vueuse/[email protected]Copy the code

2. Start encapsulation

As in the previous article, register global components using a VUE plug-in

Save the encapsulated global components under SRC/Components. In this directory, create the magnanime-images.vue file.

The code is as follows (example) :

<template>
  <div class="goods-image"> <! <div class="large" :style='[{backgroundImage: `url(${images[currIndex]})`}, bgPosition]' v-show='isShow'></div>
    <div class="middle" ref='target'> <! <img: SRC ="images[currIndex]" alt=""> <! --> <div class="layer" :style='[position]' v-show='isShow'></div>
    </div>
    <ul class="small"> <! -- thumbnail on the right --> <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: 'EnlargeImages',
  props: {
    images: {
      type: Array,
      default: () => []
    }
  },
  setup (props) {
    const currIndex = ref(0)
    const target = ref(null)
    const isShow = ref(falseConst position = reactive({left: 0, top: reactive) Reactive ({backgroundPositionX: 0, backgroundPositionY: 0, reactive(backgroundPositionX: 0, backgroundPositionY: 0, backgroundPositionY: 0)) 0}) const {elementX, elementY, isOutside} = useMouseInElement(target) IsShow. Value =! Isoutside. value // the mouse isOutside the area of the image, no need to calculate coordinatesif (isOutside.value) return// Horizontal directionif(elementx.value < 100) {// left boundary position. Left = 0}else if(elementx.value > 300) {// right border position.left = 200}else{// Middle state position.left = elementx.value-100} // Vertical directionif(elementY. Value < 100) {// position. Top = 0}else if(elementY. Value > 300) {// bottom boundary position. Top = 200}else} // console.log(elementx. value, elementY. Value, elementY. IsOutside. Value) / / computing a larger preview background position bgPosition backgroundPositionX = - position. Left * 2 +'px'
      bgPosition.backgroundPositionY = -position.top * 2 + 'px'// Calculate the left mask layer position.left +='px'
      position.top += 'px'
    })
    return { currIndex, target, isShow, position, bgPosition }
  }
}
</script>
<style scoped lang="less">
.goods-image {
  box-sizing: border-box;
  width: 480px;
  height: 400px;
  position: relative;
  display: flex;
  z-index: 500;
   img {
        width: 100%;
        height: 100%;
    }
  .large {
    position: absolute;
    top: 0;
    left: 410px;
    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, 0.2); left: 0; top: 0; position: absolute; } } .small { margin: 0; padding: 0; width: 80px; li { width: 68px; height: 68px; margin: 10px; list-style: none; cursor: pointer; &:hover, &.active { border: 2px solid#27ba9b;
      }
    }
  }
}
</style>

Copy the code

Create index.js under SRC /components

import EnlargeImages from './enlarge-images.vue'

export default {
  install (app) {
    app.component(EnlargeImages.name, EnlargeImages)
  }
}
Copy the code

Registered as a plug-in in main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// Self-encapsulated
import myUI from './components'

createApp(App).use(store).use(router).use(myUI).mount('#app')

Copy the code

Use 3.

Here we test with fixed data

The code is as follows (example) :

<template>
  <div class="home-banner"> <! Magnifying glass effect --> <enlarge-images :images="images"/>
  </div>
</template>

<script>

export default {
  name: 'App'.setup() {
    const images = [
      'https://code-1307161657.cos.ap-beijing.myqcloud.com/images%2Fcloud.jpeg'.'https://code-1307161657.cos.ap-beijing.myqcloud.com/images%2Fground.jpeg'.'https://code-1307161657.cos.ap-beijing.myqcloud.com/images%2Fnight.jpeg'.'https://code-1307161657.cos.ap-beijing.myqcloud.com/images%2Fstreet.jpeg'.'https://code-1307161657.cos.ap-beijing.myqcloud.com/images%2Fsun.jpeg'
    ]

    return { images }
  }
}
</script>

<style lang="less">
.home-banner {
  width: 1000px;
  margin: 50px auto;
}
</style>

Copy the code

Third, the effect demonstration

Move the mouse over the small picture on the right to switch the picture currently displayedPlace the mouse over the image preview area on the left. Move the mouse over the preview area to see the enlarged area on the right.


conclusion

Batch registration as a global component, you can see the vUE common tools function this article.