vue实战——商品放大镜组件封装及效果实现
Posted 北溟溟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue实战——商品放大镜组件封装及效果实现相关的知识,希望对你有一定的参考价值。
前言
本节内容以vue为基础,实现一个商品放大镜组件的封装,及动画效果实现,通过本节内容,我们也可以实现其它h5相关的功能需求。商品放大镜功能在实际开发中还是有广泛需求的,尤其在商城项目中,为了更好的使用该功能,作者将该商品放大镜功能封装为一个组件,便于使用和维护。效果如下:
正文
- 创建一个商品放大镜的组件goods-magnifier-zoom.vue
- 封装商品放大镜组件
说明:
①通过注册鼠标的移入、移出、移动事件,实现商品放大镜的效果
<div id="smallPic" @mouseover="handlerMouseOver" @mouseleave="handlerMouseLeave"
@mousemove="handlerMouseMove">
②通过父子组件实现图片数据的传递
props:
imgList:
type: Array,
required: true,
default: [],
,
,
③使用scss实现样式布局设置
<style scoped lang="scss">
④完整组件封装实现
<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"> < </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"> > </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,
,
created()
if (this.imgList.length > 0)
this.bigImgSrc = this.imgList[0].b;
this.smallImgSrc = this.imgList[0].s;
,
methods:
//鼠标移入事件
handlerMouseOver()
this.show = true;
,
//鼠标移出事件
handlerMouseLeave()
this.show = false;
,
//鼠标移动事件
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");
//蒙版边界设置
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";
,
//缩略图点击效果
thumbnailClick(data)
this.bigImgSrc = data.b;
this.smallImgSrc = data.s;
,
//点击前一个
handlerPrev()
let ul = document.querySelector('#goodsZoom #zoomBottom #picList ul');
let liNodes = document.querySelectorAll('#goodsZoom #zoomBottom #picList li');
if (liNodes.length === 0)
return;
//步长
let step = (liNodes[0].offsetWidth + 20) * 2;
this.start -= step;
if (this.start < 0)
this.start = 0;
ul.style.left = -this.start + "px";
,
//点击下一个
handlerNext()
let ul = document.querySelector('#goodsZoom #zoomBottom #picList ul');
let liNodes = document.querySelectorAll('#goodsZoom #zoomBottom #picList li');
if (liNodes.length === 0)
return;
//步长
let step = (liNodes[0].offsetWidth + 20) * 2;
//总体运动的距离值 = ul的宽度 - div框的宽度 = (图片的总数 - div中显示的数量) * (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">
.container
margin: 5px 0 15px;
overflow: hidden;
#goodsZoom
#zoomTop
width: 400px;
position: relative;
#smallPic
width: 400px;
height: 400px;
border: 1px solid #dfdfdf;
position: relative;
img
#mask
width: 200px;
height: 200px;
background: rgba(255, 255, 255, .5);
border: 1px solid #ddd;
position: absolute;
left: 0px;
top: -1px;
#bigPic
width: 400px;
height: 400px;
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: 400px;
margin-top: 5px;
a
width: 10px;
height: 54px;
border: 1px solid #ccc;
background: #ebebeb;
text-align: center;
line-height: 54px;
float: left;
text-decoration: none;
&:first-child
margin-right: 4px;
#picList
width: 372px;
height: 56px;
float: left;
overflow: hidden;
position: relative;
ul
white-space: nowrap;
font-size: 0px;
position: absolute;
left: 0px;
transition: 0.5s;
li
width: 50px;
height: 50px;
border: 1px solid #ccc;
padding: 2px;
margin-right: 20px;
display: inline-block;
img
width: 50px;
height: 50px;
</style>
- 创建一个测试页面GoodsZoom.vue,使用components引入组件
①引入组件
import goodsMagnifierZoom from '@/components/goods-magnifier-zoom.vue';
export default
name: "GoodsZoom",
components:
goodsMagnifierZoom: goodsMagnifierZoom,
②使用组件
<goods-magnifier-zoom :imgList="imgList"></goods-magnifier-zoom>
③完整代码实现
<template>
<div class="container">
<div class="title">
<span>商品放大镜</span>
<el-divider direction="vertical"></el-divider>
<router-link to="home">
<span style="font-size: 18px;">退出</span>
</router-link>
</div>
<el-divider>Test Staring</el-divider>
<goods-magnifier-zoom :imgList="imgList"></goods-magnifier-zoom>
</div>
</template>
<script>
import goodsMagnifierZoom from '@/components/goods-magnifier-zoom.vue';
export default
name: "GoodsZoom",
data()
return
imgList: [
b: require('@/assets/nav/b1.png'), s: require('@/assets/nav/s1.png'),
b: require('@/assets/nav/b2.png'), s: require('@/assets/nav/s2.png'),
b: require('@/assets/nav/b3.png'), s: require('@/assets/nav/s3.png'),
b: require('@/assets/nav/b1.png'), s: require('@/assets/nav/s1.png'),
b: require('@/assets/nav/b2.png'), s: require('@/assets/nav/s2.png'),
b: require('@/assets/nav/b3.png'), s: require('@/assets/nav/s3.png'),
b: require('@/assets/nav/b1.png'), s: require('@/assets/nav/s1.png'),
b: require('@/assets/nav/b2.png'), s: require('@/assets/nav/s2.png'),
b: require('@/assets/nav/b3.png'), s: require('@/assets/nav/s3.png'),
b: require('@/assets/nav/b1.png'), s: require('@/assets/nav/s1.png'),
b: require('@/assets/nav/b2.png'), s: require('@/assets/nav/s2.png'),
b: require('@/assets/nav/b3.png'), s: require('@/assets/nav/s3.png'),
b: require('@/assets/nav/b1.png'), s: require('@/assets/nav/s1.png'),
b: require('@/assets/nav/b2.png'), s: require('@/assets/nav/s2.png'),
b: require('@/assets/nav/b3.png'), s: require('@/assets/nav/s3.png')
],
,
components:
goodsMagnifierZoom: goodsMagnifierZoom,
</script>
<style scoped lang="scss">
.container
padding: 10px;
overflow: hidden;
.title
font-size: 20px;
font-weight: bold;
</style>
- 启动项目
- 访问页面测试组件效果
①默认效果
②鼠标移入效果
③鼠标移动效果
④点击缩略图,切换商品
⑤切换缩略图
结语
至此,关于本节内容到这里就结束了,我们下期见。。。记得点赞、关注、收藏,你的支持就是我最大的创作动力。
以上是关于vue实战——商品放大镜组件封装及效果实现的主要内容,如果未能解决你的问题,请参考以下文章