如何利用vue3实现放大镜效果实例详解

编辑: admin 分类: javascript 发布时间: 2021-11-17 来源:互联网
目录
  • 前言
  • 一、封装的意义
  • 二、如何封装?
    • 1.  准备
    • 2.  开始封装
    • 3. 使用
  • 三、 效果演示
    • 总结

      前言

      逛购物网站的时候,想必大家都见过鼠标放到商品上,会有一个放大的效果。今天我们就自己动手封装一个放大镜效果的全局组件,一起来看下吧~

      一、封装的意义

      • 从技术角度
        • 通过vue插件方式封装为全局组件,整个项目其他位置也可以使用,且使用方便
        • 模块化开发思想,一个模块实现一个功能
      • 用户角度
        • 可以带来更好的浏览体验
        • 可以看到商品的细节

      二、如何封装?

      1.  准备

      需要用到@vueuse/core的useMouseInElement方法,所以先在项目根目录下打开终端执行如下命令

      这里安装的指定版本的,各位小伙伴儿按需选择

      npm install @vueuse/core@5.3.0
      

      2.  开始封装

      还是像之前的文章一样,使用vue插件的方式注册全局组件

      在src/components下存放封装的全局组件,这个目录下新建enlarge-images.vue文件。

      代码如下(示例):

      <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">
            <!-- 右侧的缩略图 -->
             <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(false)
          // 遮罩层的坐标
          const position = reactive({
            left: 0,
            top: 0
          })
          // 控制背景图的位置
          const bgPosition = reactive({
            backgroundPositionX: 0,
            backgroundPositionY: 0
          })
          const { elementX, elementY, isOutsi日本站群服务器http://www.558idc.com/japzq.htmlde } = 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
            }
            // console.log(elementX.value, elementY.value, isOutside.value)
            // 计算预览大图背景的位置
            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 {
        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>
      
      

      src/components下新建index.js

      import EnlargeImages from './enlarge-images.vue'
      
      export default {
        install (app) {
          app.component(EnlargeImages.name, EnlargeImages)
        }
      }
      

      main.js中注册为插件

      import { createApp } from 'vue'
      import App from './App.vue'
      import router from './router'
      import store from './store'
      // 自己封装的
      import myUI from './components'
      
      createApp(App).use(store).use(router).use(myUI).mount('#app')
      
      

      3. 使用

      这里借助固定的数据进行测试

      代码如下(示例):

      <template>
        <div class="home-banner">
          <!-- 放大镜效果 -->
          <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>
      
      

      三、 效果演示

      鼠标移入右侧小图片,即可切换当前显示的图片

      鼠标放入左侧图片预览区,预览区内移动鼠标即可在右侧看到放大的指定区域

      (PS:gif图太大了,各位看下效果图吧~)

      总结

      批量注册为全局组件的方式,各位可以看下vue常用工具函数这篇文章。

      到此这篇关于如何利用vue3实现放大镜效果的文章就介绍到这了,更多相关vue3实现放大镜效果内容请搜索hwidc以前的文章或继续浏览下面的相关文章希望大家以后多多支持hwidc!