vue 2.0 實戰 移動音樂app(三)輪播圖元件的實現
阿新 • • 發佈:2018-12-21
1.slider子元件 和 recommend父元件結構。利用了slot 卡槽。簡單點來說,就是子元件預先在相應的位置留了一個坑,父元件引用了子元件以後,把對應的坑填上。
<template> <div class="slider" ref="slider"> <div class="slider-group" ref="sliderGroup"> <slot></slot> </div> <div class="dots"> <span class="dot" v-for="(item, index) in dots" :class="{'active': currentPageIndex == index}"></span> </div> </div> </template>
<div class="slider-wrapper" v-if="recommends.length">
<slider>
<div v-for="item in recommends" :key='item.id'>
<a :href="item.linkUrl">
<img :src="item.picUrl">
</a>
</div>
</slider>
</div>
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()
})
⑤