1. 程式人生 > >當better-scroll 遇見Vue

當better-scroll 遇見Vue

前言:在學習黃軼老師的《Vue.js高仿餓了麼外賣App》課程中接觸到了better-scroll第三方JavaScript元件庫,這是黃軼老師自己基於iscroll重寫的庫。這裡結合黃軼老師的知乎文章和Vue2.0專案對better-scroll的具體應用,只作為學習,對其中的原理和應用步驟做一個梳理。


            移動端專案列表滾動的需求

     豎直滾動:

      橫向滾動:

 

           什麼是better-scroll

better-scroll 是一個移動端滾動的解決方案,它是基於 iscroll 的重寫,它和 iscroll 的主要區別在這裡。better-scroll 也很強大,不僅可以做普通的滾動列表,還可以做輪播圖、picker 等等。

  • 安裝better-scroll

1

npm install better-scroll --save

  

           better-scroll 的滾動原理

      瀏覽器的滾動原理:

瀏覽器的滾動條大家都會遇到,當頁面內容的高度超過視口高度的時候,會出現縱向滾動條;當頁面內容的寬度超過視口寬度的時候,會出現橫向滾動條。也就是當我們的視口展示不下內容的時候,會通過滾動條的方式讓使用者滾動螢幕看到剩餘的內容。

      better-scroll的滾動原理:

 

  • 常用的html結構

1

2

3

4

5

6

7

8

div class="wrapper">

 

<ul class="content">

      <li></li>

      <li></li>

      <li></li>

      <li></li>

  </ul>

</div>

 當 content 的高度不超過父容器的高度,是不能滾動的,而它一旦超過了父容器的高度,我們就可以滾動內容區了,這就是 better-scroll 的滾動原理

  • 初始化better-scroll  

1

2

3

import BScroll from 'better-scroll'

let wrapper = document.querySelector('.wrapper')

let scroll = new BScroll(wrapper, {})

關於引數:better-scroll 對外暴露了一個 BScroll 的類,我們初始化只需要 new 一個類的例項即可。

               第一個引數就是我們 wrapper 的 DOM 物件,第二個是一些配置引數,具體參考 better-scroll 的文件。  

      better-scroll 的初始化時機:

  • 初始化時機很重要,因為它在初始化的時候,會計算父元素和子元素的高度和寬度,來決定是否可以縱向和橫向滾動。因此,我們在初始化它的時候,必須確保父元素和子元素的內容已經正確渲染了。如果沒有辦法滑動,那就是初始化的時機不對。
  • 如果子元素或者父元素 DOM 結構發生改變的時候,必須重新呼叫 scroll.refresh() 方法重新計算來確保滾動效果的正常。
  • 所以常見的 better-scroll 不能滾動的原因多半是初始化 better-scroll 的時機不對,或者是當 DOM 結構傳送變化的時候並沒有重新計算 better-scroll。

在《Vuejs高仿餓了麼外賣App》課程中是這樣處理的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<template>

  <div class="wrapper" ref="wrapper">

    <ul class="content">

      <li>...</li>

      <li>...</li>

      ...

    </ul>

  </div>

</template>

<script>

  import BScroll from 'better-scroll'

  export default {

    mounted() {

      this.$nextTick(() => {

        this.scroll = new Bscroll(this.$refs.wrapper, {})

      })

    }

  }

</script>

  • Vue2.0中提供了一個獲取 DOM 物件的介面—— vm.$refs,可以通過了this.$refs.wrapper訪問到了這個 DOM 物件 
  •  this.$nextTick()這個方法作用是當資料被修改後使用這個方法會回撥獲取更新後的dom再render出來; 如果不在下面的this.$nextTick()方法裡回撥這個方法,資料改變後再來計算滾動軸就會出錯

 實現效果:

  

            better-scroll不能滾動的原因

      需要DOM載入完成後才能正確應用. vue中應用在$nextTick中,非同步初始化

      子元素高度需要超過父元素。而且父元素需要設定高度(這才是better-scroll能夠滾動的原理)

      better-scroll在使用的時候,滾動只作用於第一個子元素,其它的元素都會被忽略。在vue中,獲取的ref是ratings,它的子元素包含rating-content和rating-wrapper等多個同級元素,那麼需要在這些同級元素外層,ratings內層再套一個<div>,這個<div>才是需要滾動的部分

 

1

2

3

4

5

6

7

<div class="ratings" ref="ratings">

    <div> //這才是滾動的範圍

        <div class="rating-content"></div>

        <div class="rating-wrapper"></div>

        <v-split></v-split>

    </div>

</div>

      隱藏切換顯示都會導致外掛引數的scrollerHeight:0。此時需要加上click:true,使better-scroll支援點選事件,再呼叫下refresh()重新渲染DOM就行了

1

2

3

4

5

6

7

8

9

this.$nextTick(() => {

       if(!this.scroll){

             this.scroll = new BScroll(this.$refs.food, {

                        click: true

             })

       }else{

        this.scroll.refresh();

       }

}) 


原文

https://www.cnblogs.com/ljq66/p/9984131.html