vue实现轮播图
喜欢的小伙伴可以和我互相关注哦
有任何疑问都可以私聊我
互相学习,共同进步
话不多说,先看效果
- 滚动切换、无缝切换、循环滚动
- 鼠标进入暂停自动滚动和离开继续自动滚动
主要代码:
- HTML结构
<div class="swiper">
<div class="moveL" @click="switchImg(-1)"><</div>
<div
class="container"
@mouseenter="stopAuto"
@mouseleave="startAuto">
<ul ref="showImg">
<li
v-for="(item, index) in imgArr"
:key="index"
:class="{'currentImg': index === selected}">
<img :src="item.src" alt="">
</li>
<!-- 把第一张图片复制一份到最后,实现循环滚动无回滚 -->
<li><img :src="imgArr[0].src" alt=""></li>
</ul>
</div>
<div class="moveR" @click="switchImg(-2)">></div>
<div class="footer">
<ol>
<li
v-for="(item, index) in imgArr"
:key="index"
:class="{'currentCircle': index === selected}"
@click="switchImg(index)">
</li>
</ol>
</div>
</div>
- data数据
data: {
imgArr: [ // 图片数组
{src: './img/1.jpg'},
{src: './img/2.jpg'},
{src: './img/3.jpg'},
{src: './img/4.jpg'}
],
selected: 0, // 当前展示的图片
imgWidth: 600, // 图片宽度
flag: true // 节流阀,防止连续点击切换
},
- 主要函数
- 封装图片滚动动画函数
// 封装动画函数
animate(moveX, callback){
if(this.flag){
this.flag = false; // 关闭节流阀,每次调用动画函数回调函数中打开
let ulX = this.$refs.showImg.offsetLeft;
let target = ulX + moveX; // 求出移动的目标位置
this.swiper = setInterval(()=>{ // 创建定时器移动元素
let step = (target - this.$refs.showImg.offsetLeft)/10; // 实现由快到慢的过渡效果
step = step>0 ? Math.ceil(step) : Math.floor(step); // 对每次移动的距离取整
let startX = this.$refs.showImg.offsetLeft; // 求出元素的当前位置
if(this.$refs.showImg.offsetLeft === target){ // 移动完成
clearInterval(this.swiper); // 清除先前已经创建的定时器
callback && callback();
return;
}
this.$refs.showImg.style.left = startX + step + 'px'; // 移动
}, 15);
}
},
- 实现点击左右按钮和底部圆点切换图片
// 切换图片,index传入-1代表上一张,-2代表下一张,其余代表小圆点切换
switchImg(index){
if(index === -1){ // 上一张
if(this.selected === 0){ // 如果是第一张
if(!this.flag) return; // 防止连点bug
index = this.imgArr.length;
this.$refs.showImg.style.left = -index * this.imgWidth + 'px'; // 显示至最后一张
this.animate(this.imgWidth, ()=>{
this.selected = this.imgArr.length-1; // 显示上一张
this.flag = true;
})
}else{
this.animate(this.imgWidth, ()=>{ // 显示上一张
this.selected--;
this.flag = true;
})
}
}else if(index === -2){ // 下一张
if(this.selected === this.imgArr.length-1){ // 如果是倒数第二张
index = this.imgArr.length;
this.animate(-this.imgWidth, ()=>{ // 显示下一张
this.selected = 0;
this.$refs.showImg.style.left = 0;
this.flag = true;
})
}else {
this.animate(-this.imgWidth, ()=>{
this.selected++; // 显示至第一张
this.flag = true;
})
}
}else{ // 点击下方小圆点切换图片
let oldIndex = this.selected;
this.selected = index;
let moveX = -(index - oldIndex) * this.imgWidth;
this.animate(moveX, ()=>{this.flag = true;});
}
},
- 自动切换、鼠标进入暂停和离开继续
startAuto(){ // 鼠标离开,再次自动轮播
this.autoSwitch = setInterval(()=>{ // 自动切换
this.switchImg(-2);
},2000)
},
stopAuto(){ // 鼠标移动,暂停自动轮播
clearInterval(this.autoSwitch);
},
mounted(){ // 钩子函数
this.autoSwitch = setInterval(()=>{ // 自动切换
this.switchImg(-2);
},2000)
}