Vue項(xiàng)目中使用better-scroll實(shí)現(xiàn)一個(gè)輪播圖自動(dòng)播放功能
前言
better-scroll是一個(gè)非常非常強(qiáng)大的第三方庫(kù) 在移動(dòng)端利用這個(gè)庫(kù) 不僅可以實(shí)現(xiàn)一個(gè)非常類似原生ScrollView的效果 也可以實(shí)現(xiàn)一個(gè)輪播圖的效果 這里就先記錄一下自己實(shí)現(xiàn)這個(gè)效果的一些過(guò)程吧
思路
1.首先要確定自己的HTML結(jié)構(gòu) 基本結(jié)構(gòu)就是一個(gè)wrapper包含一個(gè)content
2.其次需要明白的一個(gè)頁(yè)面可以滾動(dòng)的原理在于 當(dāng)內(nèi)容的高度超出了容器的高度才可以實(shí)現(xiàn)滾動(dòng) 如果沒(méi)有超出 那么就沒(méi)有滾動(dòng)的必要 因此第一點(diǎn)需要實(shí)現(xiàn)的就是 獲取到所有內(nèi)容的高度 由于實(shí)現(xiàn)的是一個(gè)輪播圖 所以其實(shí)整個(gè)頁(yè)面應(yīng)該想象成這樣
滾動(dòng)原理
這里可以很清楚的看到 當(dāng)頁(yè)面的橫向?qū)挾瘸隽艘暱诘膶挾?因此也就可以實(shí)現(xiàn)滾動(dòng) 綜上所述 可以看出 實(shí)現(xiàn)橫向輪播最重要的一點(diǎn)在于寬度 因此 我們首先要獲得的就是整個(gè)輪播圖的寬度
3.既然是個(gè)輪播圖 那么用戶同時(shí)也需要知道的就是 當(dāng)前播放的是第幾張圖 也就是常見(jiàn)的"小白點(diǎn)" 小白點(diǎn)的個(gè)數(shù)用于告訴用戶總共有幾張圖 而當(dāng)前播放第幾張圖則可以在小白點(diǎn)上加上一些特殊樣式的方法來(lái)告知用戶
4.輪播圖也需要一些常見(jiàn)的屬性 例如 頁(yè)面渲染以后自動(dòng)播放以及播放間隔 還有一個(gè)就是 是否支持循環(huán)輪播
理清思路以后 就可以開(kāi)始干活了 1.完善HTML結(jié)構(gòu) 其實(shí)代碼非常簡(jiǎn)單 也就是創(chuàng)建兩個(gè)div 并且添加ref引用可以方便的通過(guò)ref屬性獲取上下文
<div class="slider" ref="slider"> <div class="slider-content" ref="sliderContent"> <slot></slot> </div> </div>
這里用了vue中非常常見(jiàn)的slot插槽 為的是當(dāng)我們?cè)谕獠空{(diào)用這個(gè)slider組件的時(shí)候 可以方便的在外部傳入一些子組件
2.上文已經(jīng)提到了一些控制slider的屬性 所以需要在組件的props里接受這些屬性 便于我們?cè)谕獠糠奖愕目刂七@些屬性
props: { // 是否循環(huán)播放 loop: { type: Boolean, default: true }, // 是否自動(dòng)播放 autoPlay: { type: Boolean, default: true }, // 播放間隔 interval: { type: Number, default: 3000 } }
3.一些初始步驟的完成的差不多了以后 我們需要借助到vue的一個(gè)生命周期鉤子 mounted 也就是當(dāng)頁(yè)面渲染完畢以后 去獲取輪播圖的寬度以及初始化輪播圖的一些設(shè)置
mounted: function () { setTimeout(() => { this.setSliderWidth() this.initSlider() }, 20)
這里有一個(gè)小小的tips 就是 通常情況下 瀏覽器渲染dom的時(shí)間為17ms 所以這里使用了一個(gè)延遲函數(shù) 在20ms以后去調(diào)用這些方法 也就是確保瀏覽器的dom被正確渲染 防止出現(xiàn)一些問(wèn)題
4.上面只是調(diào)用了這個(gè)方法 還沒(méi)有實(shí)現(xiàn)這些方法 首先在設(shè)置寬度的方法里 我們需要通過(guò)$refs.sliderContent拿到上下文 并且通過(guò)一個(gè)$refs.slider.clientWidth方法拿到當(dāng)前屏幕寬度 然后遍歷這個(gè)容器 取得容器里的所有內(nèi)容 同時(shí)把獲取的內(nèi)容寬度設(shè)置為這個(gè)屏幕的寬度 最后所有的內(nèi)容的寬度相加 就可以得到整個(gè)slider的寬度 說(shuō)了這么多 感覺(jué)很繞口 所以還是看下代碼吧
// 設(shè)置slider的寬度 setSliderWidth: function (isResize) { // 獲取slider里的所有的子元素 this.children = this.$refs.sliderContent.children // console.log(this.children) // 計(jì)算寬度 = 圖片個(gè)數(shù)+每張圖片的寬度 let width = 0 // 獲取手機(jī)屏幕的寬度 let sliderWidth = this.$refs.slider.clientWidth for (let i = 0; i < this.children.length; i++) { // 獲取children里的每一項(xiàng)內(nèi)容 let child = this.children[i] child.style.width = sliderWidth + 'px' width += sliderWidth } if (this.loop) { width += 2 * sliderWidth } this.$refs.sliderContent.style.width = width + 'px' }
這樣我們就獲取了整個(gè)slider的寬度 還有一個(gè)細(xì)節(jié)在于 當(dāng)如果是loop的時(shí)候 better-scroll會(huì)在頭尾克隆兩份 所以寬度會(huì)需要*2 接下去就是實(shí)現(xiàn)一些初始化better-scroll的一些配置了 具體的參數(shù)內(nèi)容可以從better-scorll官網(wǎng)上查詢到 這里就不多做贅述了
// 設(shè)置寬度以后初始化slider initSlider: function () { this.slider = new BScroll(this.$refs.slider, { scrollX: true, scrollY: false, momentum: false, snap: { loop: this.loop, threshold: 0.3, speed: 400 }, click: true }) }
5.實(shí)現(xiàn)上述兩個(gè)方法以后 其實(shí)輪播圖基本已經(jīng)可以在頁(yè)面上看到了 大概就是長(zhǎng)成這樣 不過(guò)這樣寫完以后 會(huì)發(fā)現(xiàn)輪播圖是沒(méi)有辦法自動(dòng)輪播的以及當(dāng)前顯示的是幾張圖的樣式并沒(méi)有正確顯示 所以接下去就是實(shí)現(xiàn)這兩個(gè)方法 ps:這里的圖片數(shù)據(jù)來(lái)源什么 是請(qǐng)求了QQ音樂(lè)banner的接口文件
輪播圖的效果
6.實(shí)現(xiàn)dots樣式的正確加載 這里用到了vue中樣式的綁定
<div class="dots"> <span class="dot" v-for="(item, index) of dots" :class="{active:currentPageIndex === index}" :key="index"> </span> </div>
也就是說(shuō) 我們通過(guò)下標(biāo)來(lái)綁定樣式 同時(shí)監(jiān)聽(tīng)一個(gè)better-scroll的'scrollEnd'事件 當(dāng)滾動(dòng)結(jié)束的時(shí)候調(diào)用getCurrentPage()這個(gè)方法 這個(gè)方法會(huì)有一個(gè)返回值pageX 也就是橫向滾動(dòng)到第幾頁(yè) 把這個(gè)返回值賦值給currentPageIndex 從而達(dá)到正確顯示樣式的目的
this.slider.on('scrollEnd', () => { let page = this.slider.getCurrentPage().pageX this.currentPageIndex = page // 當(dāng)滾動(dòng)結(jié)束以后 如果是自動(dòng)播放的話 那么首先要清除定時(shí)器(防止手動(dòng)拖動(dòng)輪播圖以后圖片無(wú)法正確顯示)然后再次執(zhí)行方法 才能實(shí)現(xiàn)輪播 if (this.autoPlay) { clearTimeout(this.timer) this.play() } })
7.實(shí)現(xiàn)自動(dòng)播放功能 better-scroll也提供了一個(gè)接口goToPage(x, y, time, easing) 顧名思義也就是轉(zhuǎn)到對(duì)應(yīng)頁(yè)面 其中幾個(gè)參數(shù)分別代表 x表示橫向頁(yè)面 y表示縱向頁(yè)面 time表示動(dòng)畫執(zhí)行時(shí)間 easing一般不建議修改 有了這個(gè)接口 其實(shí)就非常輕松了 我們只需要在methods里再寫一個(gè)Play方法 具體的思路就是 通過(guò)currentPageIndex+=1得到下一張要播放的圖片的索引 同時(shí)當(dāng)索引值達(dá)到圖片數(shù)組的長(zhǎng)度的時(shí)候?qū)⒁饕匦沦x值為0就好了 并在頁(yè)面渲染了以后調(diào)用就可以了
play: function () { let playPage = this.currentPageIndex + 1 if (playPage === this.children.length - 2) { playPage = 0 } setTimeout(() => { this.slider.goToPage(playPage, 0, 400) }, this.interval) }
這里也有個(gè)細(xì)節(jié)就是 當(dāng)設(shè)置這個(gè)輪播圖為循環(huán)滾動(dòng)的時(shí)候 better-scroll會(huì)自動(dòng)在頭尾各克隆一份圖片 所以長(zhǎng)度需要減去2 這樣就可以實(shí)現(xiàn)輪播圖的自動(dòng)播放了
總結(jié)
以上所述是小編給大家介紹的Vue項(xiàng)目中使用better-scroll實(shí)現(xiàn)一個(gè)輪播圖自動(dòng)播放功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- vue實(shí)現(xiàn)自動(dòng)滑動(dòng)輪播圖片
- Vue+ECharts實(shí)現(xiàn)中國(guó)地圖的繪制及各省份自動(dòng)輪播高亮顯示
- vue-music 使用better-scroll遇到輪播圖不能自動(dòng)輪播問(wèn)題
- 使用Vue制作圖片輪播組件思路詳解
- 基于vue.js實(shí)現(xiàn)圖片輪播效果
- 基于vue.js輪播組件vue-awesome-swiper實(shí)現(xiàn)輪播圖
- Vue 過(guò)渡實(shí)現(xiàn)輪播圖效果
- vue.js+elementUI實(shí)現(xiàn)點(diǎn)擊左右箭頭切換頭像功能(類似輪播圖效果)
- vue中引用swiper輪播插件的教程詳解
- Vue實(shí)現(xiàn)首頁(yè)banner自動(dòng)輪播效果
相關(guān)文章
Vue3項(xiàng)目中reset.scss模板使用導(dǎo)入
這篇文章主要為大家介紹了Vue3項(xiàng)目中reset.scss模板使用導(dǎo)入示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09vue 解決data中定義圖片相對(duì)路徑頁(yè)面不顯示的問(wèn)題
這篇文章主要介紹了vue 解決data中定義圖片相對(duì)路徑頁(yè)面不顯示的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08一文詳解Vue選項(xiàng)式?API?的生命周期選項(xiàng)和組合式API
這篇文章主要為大家介紹了Vue選項(xiàng)式?API?的生命周期選項(xiàng)和組合式API變化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Vue中子組件調(diào)用父組件的3種方法實(shí)例
vue子組件調(diào)用父組件的方法其實(shí)不難,最近整理了一下,下面這篇文章主要給大家介紹了關(guān)于Vue中子組件調(diào)用父組件的3種方法,需要的朋友可以參考下2022-05-05詳解如何在Vue項(xiàng)目中導(dǎo)出Excel
這篇文章主要介紹了如何在Vue項(xiàng)目中導(dǎo)出Excel,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04vue之父子組件間通信實(shí)例講解(props、$ref、$emit)
組件間如何通信,也就成為了vue中重點(diǎn)知識(shí)了。這篇文章將會(huì)通過(guò)props、$ref和 $emit 這幾個(gè)知識(shí)點(diǎn),來(lái)講解如何實(shí)現(xiàn)父子組件間通信。2018-05-05Vue學(xué)習(xí)筆記進(jìn)階篇之vue-cli安裝及介紹
這篇文章主要介紹了Vue學(xué)習(xí)筆記進(jìn)階篇之vue-cli安裝及介紹,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07