一.实锤:
1.1 html:
<div class="slider" ref="slider">
<div class="slider-group" ref="sliderGroup">
<div v-for="item in recommends">
<a :href="item.linkUrl">
<img class="needsclick" @load="loadImage" :src="item.picUrl">
</a>
</div>
<div class="dots">
<span class="dot" :class="{active: currentPageIndex === index }" v-for="(item, index) in dots"></span>
</div>
</div>
1.2 script:
<script>
import BScroll from 'better-scroll'
import {addClass} from 'common/js/dom'
export default{
props: {
loop: {
type: Boolean,
default: true
},
autoPlay: {
type: Boolean,
default: true
},
interval: {
type: Number,
default: 4000
}
},
data() {
return {
dots: [],
currentPageIndex: 0
}
},
mounted() {
setTimeout(() => {
this._setSliderWidth()
this._initSlider()
this._initDots()
if (this.autoPlay) {
this._play()
}
}, 20)
window.addEventListener('resize', () => {
if (!this.slider) {
return
}
this._setSliderWidth(true)
this.slider.refresh()
})
},
methods: {
_setSliderWidth(isResize) {
// 取轮播组的子元素
this.children = this.$refs.sliderGroup.children
let width = 0
// 取轮播组件宽度(即屏幕宽度)
let sliderWidth = this.$refs.slider.clientWidth
for (var 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,
click: true
})
this.slider.on('scrollEnd', () => {
let pageIndex = this.slider.getCurrentPage().pageX
if (this.loop) {
pageIndex -= 1
}
this.currentPageIndex = pageIndex
if (this.autoPlay) {
clearTimeout(this.timer)
this._play()
}
})
},
_initDots() {
this.dots = new Array(this.children.length)
},
_play() {
let pageIndex = this.currentPageIndex + 1
if (this.loop) {
pageIndex += 1
}
this.timer = setTimeout(() => {
this.slider.goToPage(pageIndex, 0, 400)
}, this.interval)
}
}
}
</script>
二.线索:
- 可以轮播,但不能循环(不能从第一张往前翻,不能从最后一张往后翻)
- 按教程里给slider-group增加了2个slider的宽度(是为无缝循环准备的?),但他们出现在轮播图片的末尾(2个空白)
- 第一张图没有对应dot,第二张图对应第一个dot,以此类推
- 对比了教程里的代码,几乎没有区别,数据来源也是一样,替换了代码也是这样的表现,so百思不得其解
完整代码:github
找到原因了,是版本的问题,在0.1.15版本这么写是没问题的,snap的各个配置项并列写,但在新版本要写在一个snap对象内,就像采纳的答案写的那样,另外还有几个小修改,不知是个人原因还是版本差异,总之先贴出来给大家参考吧
`
- 降版本后dots会多两个:
_initDots() {
// this.dots = new Array(this.children.length) // 原写法
this.dots = new Array(this.children.length - 2)
},
2.升版本,修改创建better-scroll的配置时,dot与图片不对应:
// bs对象配置方法中(配置后):
this.slider.on('scrollEnd', () => {
let pageIndex = this.slider.getCurrentPage().pageX
// 老版本有,新版去掉:
// if (this.loop) {
// pageIndex -= 1
// }
this.currentPageIndex = pageIndex
if (this.autoPlay) {
clearTimeout(this.timer)
this._play()
}
})
新版本已经更新了,我也是找了好久
_initSlider() {