Vue項目中使用better-scroll實現一個輪播圖

前言

better-scroll是一個很是很是強大的第三方庫 在移動端利用這個庫 不只能夠實現一個很是相似原生ScrollView的效果 也能夠實現一個輪播圖的效果 這裏就先記錄一下本身實現這個效果的一些過程吧vue

思路

1.首先要肯定本身的HTML結構 基本結構就是一個wrapper包含一個content數組

2.其次須要明白的一個頁面能夠滾動的原理在於 當內容的高度超出了容器的高度才能夠實現滾動 若是沒有超出 那麼就沒有滾動的必要 所以第一點須要實現的就是 獲取到全部內容的高度 因爲實現的是一個輪播圖 因此其實整個頁面應該想象成這樣 瀏覽器

滾動原理

這裏能夠很清楚的看到 當頁面的橫向寬度超出了視口的寬度 所以也就能夠實現滾動 綜上所述 能夠看出 實現橫向輪播最重要的一點在於寬度 所以 咱們首先要得到的就是整個輪播圖的寬度bash

3.既然是個輪播圖 那麼用戶同時也須要知道的就是 當前播放的是第幾張圖 也就是常見的"小白點" 小白點的個數用於告訴用戶總共有幾張圖 而當前播放第幾張圖則能夠在小白點上加上一些特殊樣式的方法來告知用戶app

4.輪播圖也須要一些常見的屬性 例如 頁面渲染之後自動播放以及播放間隔 還有一個就是 是否支持循環輪播dom

快樂coding

理清思路之後 就能夠開始幹活了 1.完善HTML結構 其實代碼很是簡單 也就是建立兩個div 而且添加ref引用能夠方便的經過ref屬性獲取上下文ide

<div class="slider"
       ref="slider">
    <div class="slider-content"
         ref="sliderContent">
      <slot></slot>
    </div>
</div>
複製代碼

這裏用了vue中很是常見的slot插槽 爲的是當咱們在外部調用這個slider組件的時候 能夠方便的在外部傳入一些子組件函數

2.上文已經提到了一些控制slider的屬性 因此須要在組件的props裏接受這些屬性 便於咱們在外部方便的控制這些屬性oop

props: {
    // 是否循環播放
    loop: {
      type: Boolean,
      default: true
    },
    // 是否自動播放
    autoPlay: {
      type: Boolean,
      default: true
    },
    // 播放間隔
    interval: {
      type: Number,
      default: 3000
    }
  }
複製代碼

3.一些初始步驟的完成的差很少了之後 咱們須要藉助到vue的一個生命週期鉤子 mounted 也就是當頁面渲染完畢之後 去獲取輪播圖的寬度以及初始化輪播圖的一些設置動畫

mounted: function () {
   setTimeout(() => {
      this.setSliderWidth()
     this.initSlider()
   }, 20)
複製代碼

這裏有一個小小的tips 就是 一般狀況下 瀏覽器渲染dom的時間爲17ms 因此這裏使用了一個延遲函數 在20ms之後去調用這些方法 也就是確保瀏覽器的dom被正確渲染 防止出現一些問題

4.上面只是調用了這個方法 尚未實現這些方法 首先在設置寬度的方法裏 咱們須要經過$refs.sliderContent拿到上下文 而且經過一個$refs.slider.clientWidth方法拿到當前屏幕寬度 而後遍歷這個容器 取得容器裏的全部內容 同時把獲取的內容寬度設置爲這個屏幕的寬度 最後將全部的內容的寬度相加 就能夠獲得整個slider的寬度 說了這麼多 感受很繞口 因此仍是看下代碼吧

// 設置slider的寬度
    setSliderWidth: function (isResize) {
      // 獲取slider裏的全部的子元素
      this.children = this.$refs.sliderContent.children
      // console.log(this.children)
      // 計算寬度  = 圖片個數+每張圖片的寬度
      let width = 0
      // 獲取手機屏幕的寬度
      let sliderWidth = this.$refs.slider.clientWidth
      
      for (let i = 0; i < this.children.length; i++) {
        // 獲取children裏的每一項內容 
        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'
    }
複製代碼

這樣咱們就獲取了整個slider的寬度 還有一個細節在於 當若是是loop的時候 better-scroll會在頭尾克隆兩份 因此寬度會須要*2 接下去就是實現一些初始化better-scroll的一些配置了 具體的參數內容能夠從better-scorll官網上查詢到 這裏就很少作贅述了

// 設置寬度之後初始化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.實現上述兩個方法之後 其實輪播圖基本已經能夠在頁面上看到了 大概就是長成這樣 不過這樣寫完之後 會發現輪播圖是沒有辦法自動輪播的以及當前顯示的是幾張圖的樣式並無正確顯示 因此接下去就是實現這兩個方法 ps:這裏的圖片數據來源什麼 是請求了QQ音樂banner的接口文件

輪播圖的效果

6.實現dots樣式的正確加載 這裏用到了vue中樣式的綁定

<div class="dots">
      <span class="dot"
            v-for="(item, index) of dots"
            :class="{active:currentPageIndex === index}"
            :key="index">
      </span>
    </div>
複製代碼

也就是說 咱們經過下標來綁定樣式 同時監聽一個better-scroll的'scrollEnd'事件 當滾動結束的時候調用getCurrentPage()這個方法 這個方法會有一個返回值pageX 也就是橫向滾動到第幾頁 把這個返回值賦值給currentPageIndex 從而達到正確顯示樣式的目的

this.slider.on('scrollEnd', () => {
        let page = this.slider.getCurrentPage().pageX
        this.currentPageIndex = page
        // 當滾動結束之後 若是是自動播放的話 那麼首先要清除定時器(防止手動拖動輪播圖之後圖片沒法正確顯示)而後再次執行方法 才能實現輪播
        if (this.autoPlay) {
          clearTimeout(this.timer)
          this.play()
        }
      })
複製代碼

7.實現自動播放功能 better-scroll也提供了一個接口goToPage(x, y, time, easing) 顧名思義也就是轉到對應頁面 其中幾個參數分別表明 x表示橫向頁面 y表示縱向頁面 time表示動畫執行時間 easing通常不建議修改 有了這個接口 其實就很是輕鬆了 咱們只須要在methods裏再寫一個Play方法 具體的思路就是 經過currentPageIndex+=1獲得下一張要播放的圖片的索引 同時當索引值達到圖片數組的長度的時候將要索引從新賦值爲0就行了 並在頁面渲染了之後調用就能夠了

play: function () {
      let playPage = this.currentPageIndex + 1
      if (playPage === this.children.length - 2) {
        playPage = 0
      }
      setTimeout(() => {
        this.slider.goToPage(playPage, 0, 400)
      }, this.interval)
    }
複製代碼

這裏也有個細節就是 當設置這個輪播圖爲循環滾動的時候 better-scroll會自動在頭尾各克隆一份圖片 因此長度須要減去2 這樣就能夠實現輪播圖的自動播放了

###總結 到這裏就成功經過better-scroll實現了一個輪播圖的實現 具體的過程其實不算多難 主要就是理清思路 就好啦!衝鴨!

相關文章
相關標籤/搜索