vue-better-scroll 一個vue的上拉載入下拉重新整理外掛

huangjincq發表於2017-12-14

vue-better-scroll

A vue plugins based on better-scroll

最近寫移動端專案,下拉重新整理、上拉載入的場景很常見,發現 mint-ui 的 Loadmore 元件效果體驗不盡如人意, Vux 的 Scroller 元件作者不推薦使用也停止維護了,最後決定根據better-scroll封裝成自己的vue元件,作者也提供了詳細的教程。

Example

Demo Page

滾動原理

由於 better-scroll 的滾動原理為:在滾動方向上,第一個子元素的長度超過了容器的長度。

那麼對於 Scroll 元件,其實就是內容元素 .list-content 在滾動方向上的長度必須大於容器元素 .wrapper。

任何時候如果出現無法滾動的情況,都應該首先檢視內容元素 .list-content 的元素高度/寬度是否大於容器元素 .wrapper 的高度/寬度。這是內容能夠滾動的前提條件。如果內容存在圖片的情況,可能會出現 DOM 元素渲染時圖片還未下載,因此內容元素的高度小於預期,出現滾動不正常的情況。此時你應該在圖片載入完成後,比如 onload 事件回撥中,手動呼叫 vue-better-scroll 元件的 refresh() 方法,它會重新計算滾動距離。

Use Setup

Install vue2-better-scroll

yarn add vue2-better-scroll
// or
npm install vue2-better-scroll -s
複製程式碼

Vue mount

// import
import Vue from 'vue'
import VueBetterScroll from 'vue2-better-scroll'

// or require
var Vue = require('vue')
var VueBetterScroll = require('vue2-better-scroll')

// mount with global
Vue.use(VueBetterScroll)

// mount with component(can't work in Nuxt.js/SSR)
import { VueBetterScroll } from 'vue2-better-scroll'

export default {
  components: {
    VueBetterScroll
  }
}


// 或者直接匯入js檔案
<script src="./dist/vue-better-scroll.js"></script>

複製程式碼

Use in SPA

<template>
  <div id="app">
    <header>vue-better-scroll demo</header>
    <main class="position-box">  <!-- 需要一個建立一個父容器 元件高度預設等於父容器的高度 -->
      <vue-better-scroll class="wrapper"
                         ref="scroll"
                         :scrollbar="scrollbarObj"
                         :pullDownRefresh="pullDownRefreshObj"
                         :pullUpLoad="pullUpLoadObj"
                         :startY="parseInt(startY)"
                         @pullingDown="onPullingDown"
                         @pullingUp="onPullingUp">
        <ul class="list-content">
          <li class="list-item"
              v-for="item in items">{{item}}</li>
        </ul>
      </vue-better-scroll>
    </main>
    <button class="go-top"
            @click="scrollTo">返回頂部</button>
  </div>
</template>

<script>
  import VueBetterScroll from '../dist/vue-better-scroll'
  // import VueBetterScroll from './lib'

  let count = 1
  export default {
    name: 'app',
    components: { VueBetterScroll },
    data() {
      return {
        // 這個配置可以開啟滾動條,預設為 false。當設定為 true 或者是一個 Object 的時候,都會開啟滾動條,預設是會 fade 的
        scrollbarObj: {
          fade: true
        },
        // 這個配置用於做下拉重新整理功能,預設為 false。當設定為 true 或者是一個 Object 的時候,可以開啟下拉重新整理,可以配置頂部下拉的距離(threshold) 來決定重新整理時機以及回彈停留的距離(stop)
        pullDownRefreshObj: {
          threshold: 90,
          stop: 40
        },
        // 這個配置用於做上拉載入功能,預設為 false。當設定為 true 或者是一個 Object 的時候,可以開啟上拉載入,可以配置離底部距離閾值(threshold)來決定開始載入的時機
        pullUpLoadObj: {
          threshold: 0,
          txt: {
            more: '載入更多',
            noMore: '沒有更多資料了'
          }
        },
        startY: 0, // 縱軸方向初始化位置
        scrollToX: 0,
        scrollToY: 0,
        scrollToTime: 700,
        items: []
      }
    },
    mounted() {
      this.onPullingDown()
    },
    methods: {
      // 滾動到頁面頂部
      scrollTo() {
        this.$refs.scroll.scrollTo(this.scrollToX, this.scrollToY, this.scrollToTime)
      },
      // 模擬資料請求
      getData() {
        return new Promise(resolve => {
          setTimeout(() => {
            const arr = []
            for (let i = 0; i < 10; i++) {
              arr.push(count++)
            }
            resolve(arr)
          }, 1000)
        })
      },
      onPullingDown() {
        // 模擬下拉重新整理
        console.log('下拉重新整理')
        count = 0
        this.getData().then(res => {
          this.items = res
          this.$refs.scroll.forceUpdate(true)
        })
      },
      onPullingUp() {
        // 模擬上拉 載入更多資料
        console.log('上拉載入')
        this.getData().then(res => {
          this.items = this.items.concat(res)
          if (count < 30) {
            this.$refs.scroll.forceUpdate(true)
          } else {
            this.$refs.scroll.forceUpdate(false)
          }
        })
      }
    }
  }
</script>

<style>
  .position-box {
    position: fixed;
    top: 40px;
    left: 0;
    right: 0;
    bottom: 0;
  }
</style>

複製程式碼

Attributes:

引數 說明 型別 可選值 預設值
probeType 派發scroll事件的條件 Number 1、2、3 1
click better-scroll 會派發一個 click 事件 Boolean true
listenScroll 是否監聽滾動,開啟後才能派發scroll事件 Boolean false
listenBeforeScroll 是否監聽滾動之前,開啟後才能派發beforeScrollStart事件 Boolean false
direction 滾動方向 String horizontal、vertical vertical
scrollbar 這個配置可以開啟滾動條。當設定為 true 或者是一個 Object 的時候,都會開啟滾動條,預設是會 fade 的 Boolean or Object {fade: true}, false
pullDownRefresh 這個配置用於做下拉重新整理功能。當設定為 true 或者是一個 Object 的時候,可以開啟下拉重新整理,可以配置頂部下拉的距離(threshold) 來決定重新整理時機以及回彈停留的距離(stop) Boolean or Object {threshold: 90,stop: 40}, false
pullUpLoad 這個配置用於做上拉載入功能。當設定為 true 或者是一個 Object 的時候,可以開啟上拉載入,可以配置離底部距離閾值(threshold)來決定開始載入的時機 Boolean or Object { threshold: 0, txt: { more: '載入更多',noMore:'沒有更多資料了'} } false
startY 縱軸方向初始化位置 Number 0
freeScroll 有些場景我們需要支援橫向和縱向同時滾動,而不僅限制在某個方向,這個時候我們只要設定 freeScroll 為 true 即可 Boolean false

Slots:

name 說明
default 滾動的主體內容區域
pulldown 下拉重新整理的內容
pullup 上拉載入的內容

Methods:

方法名 說明 引數
initScroll 初始化scroll元件
disable 禁用 better-scroll,DOM 事件(如 touchstart、touchmove、touchend)的回撥函式不再響應
enable 啟用 better-scroll, 預設 開啟
refresh 重新計算 better-scroll,當 DOM 結構發生變化的時候務必要呼叫確保滾動的效果正常(當頁面無法滾動時,可嘗試呼叫此方法)
scrollTo 滾動到指定的位置 (scrollToX, scrollToY, scrollToTime, easing)接收4個引數,1.x橫軸座標(px) 2.y 縱軸座標(px) 3.滾動動畫執行的時長(ms) 4.easing 緩動函式,一般不建議修改
scrollToElement 滾動到指定的目標元素 (el, time, offsetX , offsetY )接收4個引數 詳情請檢視: scrollToElement
destroy 銷燬 better-scroll,解綁事件
forceUpdate 資料跟新後強制更新頁面 (dirty)接收1個 boolean 型別的引數,如果引數為true,說明還可以觸發下拉或者上拉事件,若引數為false表示之後不可拉動,一般用於資料載入全部了

Events:

事件名稱 說明 回撥引數
scroll 觸發時機:滾動過程中,具體時機取決於選項中的 probeType (觸發事件在引數中需要開啟 listenScroll ) 共1個引數,型別Object, {x, y} 滾動的實時座標
beforeScrollStart 觸發時機:滾動開始之前 (觸發事件在引數中需要開啟 listenBeforeScroll )
pullingDown 觸發時機:在一次下拉重新整理的動作後,這個時機一般用來去後端請求資料。(觸發事件在引數中需要開啟 pullDownRefresh 相關配置 )
pullingUp 觸發時機:在一次上拉載入的動作後,這個時機一般用來去後端請求資料。(觸發事件在引數中需要開啟 pullingUp 相關配置 )

目前只提供了以上常用方法、Api,如有額外需要請 issue

More detailed settings, please visit

better-scroll document

Author Blog

Gold_Gold

相關文章