1.先展示最终效果:
2.解决思路
Vue的理念是以数据驱动视图,所以拒绝通过改变元素的margin-top来实现滚动效果。写好css样式,只需改变每张图片的class即可实现轮播效果。动画效果交给transition完成。可以将轮播图看成两个(mainSlide和extraSlide),各个图片的位置如图所示:
3.代码实现
各个slide的样式:
图片宽度
$sWidth: $width - $bWidth; // 小图片宽度
$sHeight: $height / 2; // 小图片高度
#slider-wrapper{
width: $width;
height: $height;
margin: 0 auto;
cursor: pointer;
background: #ddd;
border-radius: 5px;
Box-shadow: 0 1px 6px rgba(0,0.117647),0 1px 4px rgba(0,0.117647);
display: flex;
overflow: hidden;
div{
display: inline-block;
}
}
.main-slide{
width: $bWidth;
height: $height;
float: left;
transition: all .4s ease;
}
.extra-slide{
width: $sWidth;
position: relative;
.extra-slide-item{
position: absolute;
width: $sWidth;
height: $sHeight;
left: 0;
transition: .4s ease-out;
}
.extra-slide-top{
top: -$sHeight;
}
.extra-slide-middle-first{
top: 0;
z-index: 2
}
.extra-slide-middle-second{
top: $sHeight;
z-index: 2
}
.extra-slide-bottom{
top: $height
}
.extra-slide-hide{
display: none!important;
}
}
模板包含两个轮播图:
SEOver="stop" @mouSEOut="start">
scripts部分,设置一个nowIndex,定时改变nowIndex。所有图片的class根据这个nowIndex来变化,这里使用了es6的map类型,详情点击:
this.slideLength - 1 ? i - this.slideLength : i
},slideClass(i) {
let nowIndex = this.nowIndex
// Map就是key也可以是非字符串的对象,不用Map多写几个 if else 也可以
let map = new Map([
[this.resetIndex(nowIndex),'extra-slide-top'],[this.resetIndex(nowIndex + 1),'extra-slide-middle-first'],[this.resetIndex(nowIndex + 2),'extra-slide-middle-second'],[this.resetIndex(nowIndex + 3),'extra-slide-bottom']
])
// 图片的class根据nowIndex的变化而变化
return map.get(i) ? map.get(i) : 'extra-slide-hide'
},start() {
// 定时改变nowIndex
this.slideInterval = setInterval(() => {
this.nowIndex = this.nowIndex > this.slideLength - 2 ? 0 : this.nowIndex + 1
console.log(this.nowIndex)
},2000)
},stop() {
clearInterval(this.slideInterval)
this.slideInterval = null
}
},mounted() {
this.start()
},destroyed() {
this.stop()
}
}
slideConfig,组件的props:
使用: