您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

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

51自学网 2022-05-02 21:30:49
  javascript

前言

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

一、封装的意义

  • 从技术角度
    • 通过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, 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      }      // 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实现放大镜效果内容请搜索wanshiok.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持wanshiok.com!


在项目中封装axios的实战过程
vue3封装放大镜组件的实例代码
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1