vue3实现商品图片放大镜效果(芋道源码yudao-cloud 二开笔记)

今天开发一个防某商城的商品图片放大镜,鼠标移动到图片位置时,右侧出现一个已放大的图片效果。

示例如下:

下图的图片的放大效果和小图的切换封装成了组件PicShow.vue,可根据需求自行修改,如下:

第一步:组件代码使用
javascript 复制代码
<template>
	<div>
		<!-- 大图、轮播图、放大镜 -->
	  	<PicShow :images="imgList"/>
	</div>
</template>
<script setup lang="ts">
const state = ref([
	'https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg',
	'https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg',
	'https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg',
	'https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg'
])
</script >
第二步:PicShow.vue组件代码,代码不多也比较简单,但写起来似乎并不太容易(感兴趣的朋友可以仔细看下代码注释)
javascript 复制代码
<script lang="ts" setup>
import {ref, computed} from 'vue'
import {useMouseInElement} from '@vueuse/core'

/*获取父组件的传值*/
defineProps<{
    images: string[]
}>()
// 当前显示的图片索引
let active = ref(0)
// ref 获取 DOM 元素的位置
const target = ref(null)
// isisOutside为 true 的时候代表鼠标未进入目标元素,为 false 时代表鼠标进入目标元素
const {elementX, elementY, isOutside} = useMouseInElement(target)
// 遮罩半透明图在商品大图中的坐标位置
const position = computed(() => {
    let x = elementX.value - 70
    let y = elementY.value - 70
    if (x <= 0) x = 0
    if (x >= 175) x = 175
    if (y <= 0) y = 0
    if (y >= 175) y = 175
    return {x, y}
})
</script>
<template>
    <div class="product-image">
        <!-- 右侧的图片放大效果 -->
        <div
          class="large" :style="[{ 
            backgroundImage: `url(${images[active]})`,
            backgroundPosition: `-${position.x * 2}px -${position.y * 2}px`
          }]" 
          v-show="!isOutside">
        </div>
        
        <div ref="target" class="middle">
       		<!-- 主图 -->
            <img :src="images[active]" alt=""/>
            
            <!-- 悬浮于主图上方跟着鼠标移动的遮罩层 -->
            <div class="layer" v-show="!isOutside" :style="{ left: `${position.x}px`, top: `${position.y}px` }"></div>
        </div>
        
        <!-- 下方的小轮播图 -->
        <ul class="small">
            <li v-for="(item, index) in images" :key="item" :class="{ active: index === active }" @mouseenter="active = index">
                <img :src="item" alt=""/>
            </li>
        </ul>
    </div>
</template>

<style lang="scss" scoped>
.product-image {
  position: relative;
  z-index: 500;
  .large {
    position: absolute;
    top: 0;
    left: 360px;
    width: 500px;
    height: 500px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    background-repeat: no-repeat;
    background-size: 170% 170%;
    background-color: #f8f8f8;
  }
  .middle {
    width: 350px;
    height: 350px;
    background: #f5f5f5;
    position: relative;
    cursor: move;
    .layer {
      width: 175px;
      height: 175px;
      background: rgba(0, 0, 0, 0.2);
      left: 0;
      top: 0;
      position: absolute;
    }
    img{
      width: 350px;
      height: 350px;
    }
  }
  .small {
    width: 342px;
    display: flex;
    margin-top: 5px;
    padding: 8px 8px;
    overflow-x: auto;
    margin-left: -8px;
    li {
      width: 64px;
      height: 64px;
      cursor: pointer;
      list-style: none;
      box-shadow: 0px 0px 8px #ccc;
      margin-left: 5px;
      img{
        width: 64px;
        height: 64px;
      }
    }
  }
  ul{
    margin: 0;
  }
  ul li:first-child{
    margin-left: 0 !important;
  }
}
</style>
ok了。。。。。。
相关推荐
YHPsophie2 小时前
AT3340-6T杭州中科微BDS定位授时板卡性能指标
经验分享·笔记·学习·车载系统·信息与通信
6230_2 小时前
关于HTTP通讯流程知识点补充—常见状态码及常见请求方式
前端·javascript·网络·网络协议·学习·http·html
Pandaconda3 小时前
【C++ 面试 - 新特性】每日 3 题(六)
开发语言·c++·经验分享·笔记·后端·面试·职场和发展
pan_junbiao3 小时前
Vue组件:使用$emit()方法监听子组件事件
前端·javascript·vue.js
hummhumm3 小时前
数据库系统 第46节 数据库版本控制
java·javascript·数据库·python·sql·json·database
手打猪大屁3 小时前
STM32——串口通信(发送/接收数据与中断函数应用)
经验分享·笔记·stm32·单片机·嵌入式硬件
贾saisai4 小时前
Xilinx系FPGA学习笔记(四)VIO、ISSP(Altera)及串口学习
笔记·学习·fpga开发
月夕花晨3744 小时前
C++学习笔记(13)
c++·笔记·学习
probably1214 小时前
学习记录之Java学习笔记3
java·笔记·学习
Loong_DQX4 小时前
【前端】vue+html+js 实现table表格展示,以及分页按钮添加
前端·javascript·vue.js