主要html架构
解释:
主要CSS代码
/* slider组件的主要CSS代码 */
.slider-wrapper {
position: relative;
width: 100%; /*撑满父容器*/
height: 100%; /*撑满父容器*/
min-height: 1px;
overflow: hidden;
}
.slider-ul {
/* mounted的时候设定ul的宽度,设定方法是100% x 多少个图片item,如5个图片项则是500% */
/* 如果是假数据进行样式设定调试,可以先设定width为多少个100% */
position: relative;
white-space: nowrap;
overflow: hidden; /*清除浮动*/
height: 100%;
}
.slider-li {
/* 同样是 mounted时设定一个item的宽度,宽度要和slider-wrapper的宽度一样,则 500% * 0.2 = 100% */
/* 同样是假数据的样式调试的时候,可以先设定width,如slider-wrapper为100%,slider-ul为500%,即有五张图片,此时设定slider-li的width为20%,500 * 0.2 = 100,则和slider-wrppaer宽度一致 */
height: 100%;
float: left; /*要设置浮动*/
box-sizing: border-box;
overflow: hidden;
}
.slider-li a {
overflow: hidden;
width: 100%;
height: 100%;
display: block;
}
.slider-li img {
width: 100%;
height: 100%;
display: block;
}
组件主要部分
// props,父组件传入子组件的参数
props: {
loop: { //是否循环播放
type: Boolean,
default: true
},
autoPlay: { //是否自动播放
type: Boolean,
default: true
},
interVal: { //轮播一张图片的时间
type: Number,
default: 3000
},
imgDatas: { //传入的imgDatas数据
type: Array,
default: []
}
}
//主要内置数据
data() {
return {
currentPageIndex: 0 //记录当前是哪一张轮播图图片,下标从0开始,即第一张
}
}
//methods
methods:{
//第一步,根据传入的imgDatas初始化slider-ul,slider-li的宽度,为百分比
//注意,better-scroll在初始化时,当你设定了loop的时候,会在前后自动增加2张图片,例如5张图片会变成7张
//由于这是第一步,暂时没有初始化better-scroll,所以获取children的时候,只是5张图片,props的loop为true时,要加多两个,然后设定ul,li的宽度
_setUlWidth() {
this.children = this.$refs.sliderUl.children
let childrenLength = this.loop ? this.children.length + 2 : this.children.length
this.$refs.sliderUl.style.width = childrenLength * 100 + '%'
for (var i = 0; i < this.children.length; i++) {
this.children[i].style.width = 100 / childrenLength + '%'
}
},
//第二步,初始化better-scroll
_initSlider() {
let that = this
this.slider = new BScroll(this.$refs.sliderWrapper, {
scrollX: true,
scrollY: false,
momentum: false,
snap: {
loop: this.loop,
threshold: 0.3,
speed: 400
},
probeType: 2
})
//监听scroll结束的时候,赋值更新currentPageIndex
this.slider.on('scrollEnd', () => {
clearInterval(that.timer)
that.currentPageIndex = that.slider.getCurrentPage().pageX
let childrenLength = this.loop ? this.children.length - 2 : this.children.length
that._setAutoplay()
})
let childrenLength = this.loop ? this.children.length - 2 : this.children.length
//无缝
this.checkScroll(childrenLength,this.$refs.sliderWrapper.offsetWidth)
},
//第三步,设置自动播放
//这一步不需要重新设定currentPageIndex ,因为转到下一页时触发了scrollEnd事件,已经自动赋值更新
_setAutoplay() {
let goToIndex = this.currentPageIndex + 1
let childrenLength = this.loop ? this.children.length - 2 : this.children.length
//设置右滑到最后一张的无缝切换,返回到第一张
if (goToIndex >= childrenLength) {
goToIndex = 0
}
this.timer = setInterval(() => {
this.slider.goToPage(goToIndex, 0, 400)
}, this.interVal)
},
//监听滑事件
checkScroll(childrenLength,itemWidth) {
let that = this
this.slider.on('scroll', () => {
clearInterval(that.timer)
let leftScroll = parseInt(that.$refs.sliderUl.style['transform'].substring(10, 15))
let left = -1 * itemWidth
let right = left * childrenLength
if (leftScroll >left) {
that.slider.goToPage(childrenLength, 0, 400)
}else if(leftScroll < right) {
that.slider.goToPage(1, 0, 400)
}
})
}
},
mounted() {
setTimeout(() => {
this._setUlWidth()
this._initSlider()
this._setAutoplay()
}, 20)
window.addEventListener('resize', () => {
if (!this.slider) {
return
}
this._setUlWidth()
})
}
这样已经可以轮播了哦,更详细的样式和功能代码看下面的源代码
源代码
使用说明:
imgDatas: [
{ imgSrc: require("./images/1.jpg"), linkUrl: '#' },
{ imgSrc: require("./images/2.jpg"), linkUrl: '#' },
{ imgSrc: require("./images/3.jpg"), linkUrl: '#' },
{ imgSrc: require("./images/4.jpg"), linkUrl: '#' },
]