移动端轮播图——Vue
喜欢的小伙伴可以和我互相关注哦
有任何疑问都可以私聊我
互相学习,共同进步
pc端轮播图主页里也有哦
还是老样子,先看效果图
具体实现代码解析
- HTML结构
<div class="swiper"> <div class="container"> <ul ref="imgBox" @transitionend="animateEnd" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"> <!-- 过渡结束事件、开始触摸、触摸移动和触摸结束事件 --> <!-- 为了实现无缝循环滚动需要在li前后分别复制最后一张图片和第一张图片 --> <li><img :src="imgArr[imgArr.length-1].src" alt=""></li> <li v-for="(item, index) in imgArr" :key="index" > <img :src="item.src" alt=""> </li> <li><img :src="imgArr[0].src" alt=""></li> </ul> </div> <div class="circle"> <ol> <li v-for="(item, index) in imgArr" :key="index" :class="{current: index===circleIndex}"> </li> </ol> </div> </div>
- 数据说明
imgArr: [ {src: './img/1.jpg'}, {src: './img/2.jpg'}, {src: './img/3.jpg'}, {src: './img/4.jpg'} ], flag: true, // 节流阀 防止快速滑动 circleIndex: 0, // 当前展示图片对应圆点 imgIndex: 0, // 当前展示图片 timer: null, // 圆点定时器 imgWidth: 0, // 图片宽度 startX: 0, // 手指开始触摸位置 moveX: 0, // 手指移动距离 interval: 2000 // 滚动间隔时间
- 过渡结束函数
animateEnd(){ // 过渡结束事件 if(this.imgIndex >= this.imgArr.length){ // 判断当前图片索引是否为最后一张图 this.imgIndex = 0; this.$refs.imgBox.style.transition = 'none'; // 迅速跳转至第一张图 this.$refs.imgBox.style.transform = `translateX(-${this.imgWidth}px)`; } if(this.imgIndex < 0){ // 判断当前图片索引是否为第一张图 this.imgIndex = this.imgArr.length-1; this.$refs.imgBox.style.transition = 'none'; // 迅速跳转至最后一张图 this.$refs.imgBox.style.transform = `translateX(${this.translateX}px)`; } this.flag = true; // 打开节流阀 },
- 触摸事件
touchstart(event){ // 手指开始触摸事件 clearInterval(this.timer); // 关闭自动轮播 if(this.flag){ this.startX = event.targetTouches[0].clientX; // 获取开始触摸位置 } }, touchmove(event){ // 手指开始移动 if(this.flag){ this.moveX = event.targetTouches[0].clientX - this.startX; // 手指移动位置 this.$refs.imgBox.style.transition = 'none'; // 图片ul跟随手指移动 this.$refs.imgBox.style.transform = `translateX(${this.translateX + this.moveX}px)`; } }, touchend(event){ // 结束触摸 if(this.flag){ if(this.moveX > 80){ // 移动距离大于80,图片索引-- this.imgIndex--; this.circleIndex--; } else if(this.moveX < -80){ // 移动距离小于-80,图片索引++ this.imgIndex++; this.circleIndex++; } this.$refs.imgBox.style.transition = 'all .5s'; // 展示当前索引图片 this.$refs.imgBox.style.transform = `translateX(${this.translateX}px)`; } // 触摸事件完成,继续自动轮播 clearInterval(this.timer); // 防止定时器叠加 this.timer = setInterval(()=>{ this.imgIndex++; this.circleIndex++; this.$refs.imgBox.style.transition = 'all .5s'; this.$refs.imgBox.style.transform = `translateX(${this.translateX}px)`; }, this.interval); this.flag = false; // 关闭节流阀,等待动画完成 }
- 数据监听和计算
watch: { circleIndex(){ // 监视原点索引变化 if(this.circleIndex >= this.imgArr.length){ this.circleIndex = 0; } if(this.circleIndex < 0){ this.circleIndex = this.imgArr.length-1; } } }, computed: { translateX(){ // 计算图片ul当前距离 return -(this.imgWidth + this.imgWidth * this.imgIndex); } },
- mounted钩子函数
mounted() { this.imgWidth = window.innerWidth; // 获取图片宽度 // ul先左移动一个图片距离,显示第一张图片 this.$refs.imgBox.style.transform = `translateX(-${this.imgWidth}px)`; this.timer = setInterval(()=>{ // 自动轮播 this.imgIndex++; this.circleIndex++; this.$refs.imgBox.style.transition = 'all .5s'; // 切换下一张图片 this.$refs.imgBox.style.transform = `translateX(${this.translateX}px)`; }, this.interval) }