1.新建Imgzoom組件代碼如下:
<template>
<div class="container">
<div id="goodsZoom">
<div id="zoomTop">
<!-- 小圖框-->
<div id="smallPic" @mouseover="handlerMouseOver" @mouseleave="handlerMouseLeave"
@mousemove="handlerMouseMove">
<img :src="smallImgSrc">
<!-- 蒙版元素-->
<div id="mask" v-show="show"></div>
</div>
<!-- 大圖框-->
<div id="bigPic" v-show="show">
<img :src="bigImgSrc" id="bigImg">
</div>
</div>
<div id="zoomBottom">
<a href="javascript:;" class="prev" @click="handlerPrev" v-if="prevShow"><i class="el-icon-caret-left"></i></a>
<div id="picList">
<ul>
<li v-for="(item,index) in imgList" @click="thumbnailClick(item)">
<img :src="item.s">
</li>
</ul>
</div>
<a href="javascript:;" class="next" @click="handlerNext" v-if="prevShow"> <i class="el-icon-caret-right"></i> </a>
</div>
</div>
</div>
</template>
<script>
export default {
name: "goods-magnifier-zoom",
props: {
imgList: {
type: Array,
required: true,
default: [],
},
},
data() {
return {
show: false,//是否顯示
bigImgSrc: '',
smallImgSrc: '',
start: 0,
prevShow:false,
}
},
created() {
if (this.imgList.length > 0) {
this.bigImgSrc = this.imgList[0].b;
this.smallImgSrc = this.imgList[0].s;
}
this.prevShow = this.imgList.length >4?true:false;
},
methods: {
//鼠標(biāo)移入事件
handlerMouseOver() {
this.show = true;
},
//鼠標(biāo)移出事件
handlerMouseLeave() {
this.show = false;
},
//鼠標(biāo)移動(dòng)事件
handlerMouseMove(data) {
const smallPic = document.getElementById("smallPic");
const bigPic = document.getElementById("bigPic");
const bigImg = document.getElementById("bigImg");
const zoomTop = document.getElementById("zoomTop");
const mask = document.getElementById("mask");
//蒙版邊界設(shè)置
let left = data.clientX - smallPic.getBoundingClientRect().left - mask.offsetWidth / 2;
let top = data.clientY - smallPic.getBoundingClientRect().top - mask.offsetHeight / 2;
//邊界判斷
if (left < 0) {
left = 0;
} else if (left > smallPic.clientWidth - mask.offsetWidth) {
left = smallPic.clientWidth - mask.offsetWidth;
}
if (top < -1) {
top = -1;
} else if (top > smallPic.clientHeight - mask.offsetHeight) {
top = smallPic.clientHeight - mask.offsetHeight;
}
mask.style.left = left + "px";
mask.style.top = top + "px";
let scale = (smallPic.clientWidth - mask.offsetWidth) / (bigImg.offsetWidth - bigPic.clientWidth);
console.log(scale);
bigImg.style.left = -left / scale + "px";
bigImg.style.top = -top / scale + "px";
},
//縮略圖點(diǎn)擊效果
thumbnailClick(data) {
this.bigImgSrc = data.b;
this.smallImgSrc = data.s;
},
//點(diǎn)擊前一個(gè)
handlerPrev() {
let ul = document.querySelector('#goodsZoom #zoomBottom #picList ul');
let liNodes = document.querySelectorAll('#goodsZoom #zoomBottom #picList li');
if (liNodes.length === 0) {
return;
}
//步長(zhǎng)
let step = (liNodes[0].offsetWidth + 20) * 2;
this.start -= step;
if (this.start < 0) {
this.start = 0;
}
ul.style.left = -this.start + "px";
},
//點(diǎn)擊下一個(gè)
handlerNext() {
let ul = document.querySelector('#goodsZoom #zoomBottom #picList ul');
let liNodes = document.querySelectorAll('#goodsZoom #zoomBottom #picList li');
if (liNodes.length === 0) {
return;
}
//步長(zhǎng)
let step = (liNodes[0].offsetWidth + 20) * 2;
//總體運(yùn)動(dòng)的距離值 = ul的寬度 - div框的寬度 = (圖片的總數(shù) - div中顯示的數(shù)量) * (li的寬度 + 20)
let endPosition = (liNodes.length - 5) * (liNodes[0].offsetWidth + 20);
this.start += step;
if (this.start > endPosition) {
this.start = endPosition;
}
ul.style.left = -this.start + "px";
},
},
};
</script>
<style scoped lang="scss">
*{
padding: 0;
margin: 0;
}
.container {
margin: 5px 0 15px;
overflow: hidden;
#goodsZoom {
width: 500px;
#zoomTop {
width: 500px;
position: relative;
#smallPic {
width: 500px;
height: 350px;
border: 1px solid #dfdfdf;
position: relative;
img {
width: 100%;
height: 100%;
}
#mask {
width: 200px;
height: 200px;
background: rgba(255, 255, 255, .5);
border: 1px solid #ddd;
position: absolute;
left: 0px;
top: -1px;
}
}
#bigPic {
margin-left: 90px;
width: 500px;
height: 350px;
border: 1px solid #ddd;
left: 420px;
top: 0px;
position: absolute;
overflow: hidden;
#bigImg {
width: 800px;
height: 800px;
position: absolute;
left: 0px;
top: 0px;
}
}
}
#zoomBottom {
width: 500px;
margin-top: 5px;
a {
width: 20px;
height: 20px;
background: #409eff;
text-align: center;
line-height: 20px;
border-radius: 50px;
float: left;
text-decoration: none;
color:#ffffff;
&:first-child {
margin-right: 4px;
margin-top: 18px;
}
.el-icon-caret-left{
margin: 2px 2px 2px 0;
}
}
.next{
margin-top: 18px;
.el-icon-caret-right{
margin:2px;
}
}
#picList {
width: 455px;
height: 56px;
float: left;
overflow: hidden;
position: relative;
ul {
white-space: nowrap;
font-size: 0px;
position: absolute;
left: 0px;
transition: 0.5s;
li {
width: 80px;
height: 50px;
padding: 2px;
margin-right: 10px;
display: inline-block;
cursor: pointer;
img {
width: 80px;
height: 50px;
}
}
}
}
}
}
}
</style>
2.在頁(yè)面中使用
<template>
<div class="dashboard-container">
<ImgZoom :imgList="imgList" />
</div>
</template>
<script>
import ImgZoom from '@/components/imgZoom'
export default {
name: 'Dashboard',
components: {
ImgZoom
},
data() {
return {
imgList: [
{b: require('@/assets/ban-01.png'), s: require('@/assets/ban-01.png')},
{b: require('@/assets/ban-02.png'), s: require('@/assets/ban-02.png')},
{b: require('@/assets/ban-03.png'), s: require('@/assets/ban-03.png')},
{b: require('@/assets/ban-04.png'), s: require('@/assets/ban-04.png')}
]
}
}
}
</script>
<style lang="scss" scoped>
</style>