Vue3 实现类似淘宝、京东产品详情图片放大器功能
环境:vue3+ts+vite
1.创建picShow.vue组件
<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 >= 140) x = 140
if (y <= 0) y = 0
if (y >= 140) y = 140
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: 290px;
width: 500px;
height: 500px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
background-repeat: no-repeat;
background-size: 156% 156%;
background-color: #f8f8f8;
}
.middle {
width: 280px;
height: 280px;
background: #f5f5f5;
position: relative;
cursor: move;
.layer {
width: 140px;
height: 140px;
background: rgba(0, 0, 0, 0.2);
left: 0;
top: 0;
position: absolute;
}
img{
width: 280px;
height: 280px;
}
}
.small {
width: 280px;
display: flex;
margin-top: 5px;
li {
width: 70px;
height: 70px;
cursor: pointer;
list-style: none;
img{
width: 70px;
height: 70px;
}
}
}
}
</style>
2.在其他页面引用组件picShow.vue
<div class="product-info">
<div class="media">
<PicShow :images="picList"/>
</div>
</div>
//js部分
import PicShow from "@/components/picShow.vue";
const picList=[
'/src/assets/images/contactus01.jpg',
'/src/assets/images/contactus02.jpg',
'/src/assets/images/contactus03.jpg',
'/src/assets/images/contactus04.jpg',
]
效果: