使用better-scroll 封裝滾動加載組件

<template>
  <div ref="wrapper">
    <slot></slot>
  </div>
</template>
<script type="text/ecmascript-6">
  import BScroll from 'better-scroll'

  export default {
    props: {
      /**
       * 1 滾動的時候會派發scroll事件,會截流。
       * 2 滾動的時候實時派發scroll事件,不會截流。
       * 3 除了實時派發scroll事件,在swipe的情況下仍然能實時派發scroll事件
       */
      probeType: {
        type: Number,
        default: 1
      },
      /**
       * 點擊列表是否派發click事件
       */
      click: {
        type: Boolean,
        default: true
      },
      /**
       * 是否開啓橫向滾動
       */
      scrollX: {
        type: Boolean,
        default: false
      },
      /**
       * 是否派發滾動事件
       */
      listenScroll: {
        type: Boolean,
        default: false
      },
      /**
       * 列表的數據
       */
      data: {
        type: Array,
        default: null
      },
      /**
       * 是否派發滾動到底部的事件,用於上拉加載
       */
      pullup: {
        type: Boolean,
        default: false
      },
      /**
       * 是否派發頂部下拉的事件,用於下拉刷新
       */
      pulldown: {
        type: Boolean,
        default: false
      },
      /**
       * 是否派發列表滾動開始的事件
       */
      beforeScroll: {
        type: Boolean,
        default: false
      },
      /**
       * 當數據更新後,刷新scroll的延時。
       */
      refreshDelay: {
        type: Number,
        default: 20
      }
    },
    mounted() {
      // 保證在DOM渲染完畢後初始化better-scroll
      setTimeout(() => {
        this._initScroll()
      }, 20)
    },
    methods: {
      _initScroll() {
        if (!this.$refs.wrapper) {
          return
        }
        // better-scroll的初始化
        this.scroll = new BScroll(this.$refs.wrapper, {
          probeType: this.probeType,
          click: this.click,
          scrollX: this.scrollX
        })

        // 是否派發滾動事件
        if (this.listenScroll) {
          this.scroll.on('scroll', (pos) => {
            this.$emit('scroll', pos)
          })
        }

        // 是否派發滾動到底部事件,用於上拉加載
        if (this.pullup) {
          this.scroll.on('scrollEnd', () => {
            // 滾動到底部
            if (this.scroll.y <= (this.scroll.maxScrollY + 50)) {
              this.$emit('scrollToEnd')
            }
          })
        }

        // 是否派發頂部下拉事件,用於下拉刷新
        if (this.pulldown) {
          this.scroll.on('touchend', (pos) => {
            // 下拉動作
            if (pos.y > 50) {
              this.$emit('pulldown')
            }
          })
        }

        // 是否派發列表滾動開始的事件
        if (this.beforeScroll) {
          this.scroll.on('beforeScrollStart', () => {
            this.$emit('beforeScroll')
          })
        }
      },
      disable() {
        // 代理better-scroll的disable方法
        this.scroll && this.scroll.disable()
      },
      enable() {
        // 代理better-scroll的enable方法
        this.scroll && this.scroll.enable()
      },
      refresh() {
        // 代理better-scroll的refresh方法
        this.scroll && this.scroll.refresh()
      },
      scrollTo() {
        // 代理better-scroll的scrollTo方法
        this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments)
      },
      scrollToElement() {
        // 代理better-scroll的scrollToElement方法
        this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
      }
    },
    watch: {
      // 監聽數據的變化,延時refreshDelay時間後調用refresh方法重新計算,保證滾動效果正常
      data() {
        setTimeout(() => {
          this.refresh()
        }, this.refreshDelay)
      }
    }
  }
</script>
<template>
  <scroll class="wrapper"
          :data="data"
          :pulldown="pulldown"
          @pulldown="loadData">
    <ul class="content">
      <li v-for="item in data">{{item}}</li>
    </ul>
    <div class="loading-wrapper"></div>
  </scroll>
</template>
<script>
  import BScroll from 'better-scroll'
  export default {
    data() {
      return {
        data: [],
        pulldown: true
      }
    },
    created() {
      this.loadData()
    },
    methods: {
      loadData() {
        requestData().then((res) => {
          this.data = res.data.concat(this.data)
        })
      }
    }
  }
</script>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章