单独封装slider组件
父组件
<slider>
<div v-for="item in recommends">
<a href="item.linkUrl">
<img :src="item.picUrl">
</a>
</div>
</slider>
子组件
<div class="slider" ref="slider">//最外层wrapper
<div class="slider-group" ref="sliderGroup">//content层
<slot>
</slot>
</div>
</div>
每一张图片的宽度为slider的宽度,所以slider-group的宽度为所有图片宽度的总和
``` mounted() { setTimeout(() => { this._setSliderWidth() this._initDots() this._initSlider() if (this.autoPlay) {
this._play()
}
}, 20)//通常情况下 浏览器渲染dom的时间为17ms 所以这里使用了一个延迟函数 在20ms以后去调用这些方法 也就是确保浏览器的dom被正确渲染 防止出现一些问题
window.addEventListener('resize', () => {
if (!this.slider) return
// 窗口改变的大小时重新计算clienWidth 此时不需要再加上两个多余的width
this._setSliderWidth(true)
this.slider.refresh()
})
},
```
_setSliderWidth(isResize) {
this.children = this.$refs.sliderGroup.children //所有图片
let width = 0
let sliderWidth = this.$refs.slider.clientWidth //取得视口宽度即为每个图片宽度
for (let i = 0; i < this.children.length; i++) {
let child = this.children[i]
addClass(child, 'slider-item')
child.style.width = sliderWidth + 'px'
width += sliderWidth //获取所有图片的总宽度,即是图片的父元素的宽度
}
if (this.loop && !isResize) {
width += 2 * sliderWidth //当是循环播放的时候,会在头部和尾部各多准备一张图片,所以宽度要加上两张,但是如果是重置视口大小是不需要多方两张的
}
this.$refs.sliderGroup.style.width = width + 'px'
},
_initSlider() {
this.slider = new BScroll(this.$refs.slider, {
scrollX: true,
scrollY: false,
momentum: false,
snap: true,
snapLoop: this.loop,
snapThreshold: 0.3,
snapSpeed: 400
})
// 获取当前页 currentPageIndex
this.slider.on('scrollEnd', () => {
let pageIndex = this.slider.getCurrentPage().pageX //getCurrentPage().pageX获取x轴显示的哪一页。
if (this.loop) {
pageIndex -= 1 //因为pageIndex下标从1开始,所以为了和index对应,要减一
}
this.currentPageIndex = pageIndex
if (this.autoPlay) {//
// 当滚动结束以后 如果是自动播放的话 那么首先要清除定时器(防止手动拖动轮播图以后图片无法正确显示)然后再次执行方法 才能实现轮播
clearTimeout(this.timer)
this._play()
}
})
this.slider.on('beforeScrollStart', () => {
if (this.autoPlay) {
clearTimeout(this.timer)
}
})
},