1.slider子组件 和 recommend父组件结构。利用了slot 卡槽。简单点来说,就是子组件预先在相应的位置留了一个坑,父组件引用了子组件以后,把对应的坑填上。
2.利用'better-scroll'实现轮播特效,首先在package.json引入相关依赖,对应的js引入'better-scroll'
3.'better-scroll'利用的原理就是:wrapper为父容器,具有固定高度;content为父容器的第一个子元素;当content的高度超过wrapper时,就可以滚动。
①轮播图的功能有:循环轮播,自动轮播,轮播间隔。
props: {
loop: {
type: Boolean,
default: true
},
autoPlay: {
type: Boolean,
default: true
},
interval: {
type: Number,
default: 4000
}
},
实现水平轮播最重要的是计算轮播宽度
_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'
},
这里我有个疑惑的地方:
if (this.loop && !isResize) {
width += 2 * sliderWidth
}
为何实现循环,需要在前后各加两项的宽度???
宽度定义好以后,就可以初始化滚动了
_initSlider() {
this.slider = new BScroll(this.$refs.slider, {
scrollX: true,//横向滚动
scrollY: false,//禁止纵向滚动
momenton: false,//禁止惯性运动
snap: true,
snapLoop: this.loop,
snapThreshold: 0.3,
snapSpeed: 400
})
},
②将滚动与对应的圆点对应起来
改变currentPageIndex的值,改变对应于那个圆点的特殊样式。思路:初始化滚动时,每一次滚动结束时,获取滚动单元对应的序号,将此序号赋值给currentPageIndex。loop为true时,对应序号减一。
this.slider.on('scrollEnd', () => {
let pageIndex = this.slider.getCurrentPage().pageX
if (this.loop) {
pageIndex -= 1
}
this.currentPageIndex = pageIndex
③实现自动轮播。滚动自带函数goToPage()。0:纵向不需要移动
_play() {
let pageIndex = this.currentPageIndex + 1
if (this.loop) {
pageIndex += 1
}
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.slider.goToPage(pageIndex, 0, 400)
}, this.interval)
}
此时自动轮播只会执行一次,需要在scrollEnd时,检测this.autoPlay,继续执行自动轮播。
④每次更改视口大小,需要重新计算轮播宽度
window.addEventListener('resize', () => {
if (!this.slider) {
return
}
this._setSliderWidth(true)
this.slider.refresh()
})
⑤