每天学习一个vue插件(1)——better-scroll

1,497 阅读2分钟

有些鸟儿是注定关不住的,因为它们的每一片羽毛都闪耀着自由的光辉

前言

开始啦,就这样开始了,有点小激动,也有点小忐忑
加油吧,每天进步一点点,一点点就好😄

1 介绍

常用配置项

const options = {
  // 允许派发滚动事件
  probeType: 1,
  // 垂直滚动时,允许同时出现横向滚动条
  eventPassthrough: 'horizontal',
  // 允许原生点击事件
  click: true,
  // 允许触屏点击
  tap: 'tap'
}

常用属性

maxScrollY

// 最大纵向距离,盒子最大高度,一般为负值
// 用于判断是否滚动到底部 pos.y < maxScrollY
bs.maxScrollY

常用方法

refresh

// 重新计算滚动区域
// 拉取数据,改变DOM需要调用该方法
bs.refresh()

scrollTo

// 滚动到指定位置
// 返回顶部时使用
bs.scrollTo(x, y)

scrollToElement

// 滚动到指定元素
// 元素置顶时使用
bs.scrollToElement(el)

常用事件

scrollStart

// 滚动开始时触发
// 用于数据重置
bs.on('scrollStart', () => {})

scroll

// 滚动时触发
// 用于判断触顶 pos.y === 0
// 触底 pos.y === maxScrollY
bs.on('scroll', pos => console.log(pos.x, pos.y))

touchEnd

// 手指离开时触发
// 用于下拉刷新和上拉加载
bs.on('touchEnd', () => {})

特殊事件

pullingUp

  // 必须导入并注册对应插件,才能使用
  import BetterScroll from '@better-scroll/core'
  import Pullup from '@better-scroll/pull-up'

  BetterScroll.use(Pullup)
  const bs = new BetterScroll('.wrapper', {
    pullUpLoad: true
  })

  bs.on('pullingUp', async () => {
    await fetchData()
    bs.finishPullUp()
  })

pullingDown

  // 必须导入并注册对应插件,才能使用
  import BetterScroll from '@better-scroll/core'
  import Pulldown from '@better-scroll/pull-down'

  BetterScroll.use(Pulldown)
  const bs = new BetterScroll('.wrapper', {
    pullDownRefresh: true
  })

  bs.on('pullingDown', async () => {
    await fetchData()
    bs.finishPullDown()
  })

2 使用

安装

全部安装

npm install better-scroll --save

按需安装

npm install @better-scroll/core --save
npm install @better-scroll/pull-up --save

滚动

按需导入

<template>
  <div class="BScroll" ref="BScroll">
    <div class="content">
      <div class="pull-down" v-show="!isLoading">
        {{pullDownMsg}}
      </div>
      <p v-show="isLoading">加载中...</p>
      <ul>
        <li v-for="(item, index) in list" :key="index">{{item}}</li>
      </ul>
      <div class="pull-up" v-show="!isLoading">
        {{pullUpMsg}}
      </div>
      <p v-show="isLoading">加载中...</p>
    </div>
  </div>
</template>

<script>
import BScroll from '@better-scroll/core'
import Pulldown from '@better-scroll/pull-down'
import Pullup from '@better-scroll/pull-up'
BScroll.use(Pulldown).use(Pullup)

export default {
  name: 'BScroll',
  data () {
    return {
      bs: null,
      options: {
        // 允许派发滚动事件
        probeType: 1,
        // 允许原生点击事件
        click: true,
        // 开启下拉刷新
        pullDownRefresh: {
          threshold: 50,
          stop: 0
        },
        // 开启上拉加载
        pullUpLoad: {
          threshold: 50
        }
      },
      pullDownMsg: '下拉刷新',
      pullUpMsg: '上拉加载',
      list: Array.from({ length: 10 }, (v, i) => i),
      total: 20,
      isLoading: false
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    fetchData () {
      return new Promise(resolve => {
        const list = Array.from({ length: 10 }, (v, i) => i + 1)
        setTimeout(() => resolve(list), 1000)
      })
    },
    init () {
      this.bs = new BScroll(this.$refs.BScroll, this.options)

      this.bs.on('pullingDown', async (pos) => {
        this.isLoading = true
        console.log('pullingDown', pos)
        const list = await this.fetchData()
        this.isLoading = false
        this.list = list
        this.bs.finishPullDown()
      })

      this.bs.on('pullingUp', async (pos) => {
        if (this.list.length >= this.total) {
          this.pullUpMsg = '我是有底线的'
          return
        }

        this.isLoading = true
        console.log('pullingUp', pos)
        const list = await this.fetchData()
        this.isLoading = false
        this.list.push(...list)
        this.bs.finishPullUp()
        this.$nextTick(() => this.bs.refresh())
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.BScroll {
  height: 500px;
  overflow: hidden;
  .pull-down {
    line-height: 40px;
    transform: translateY(-100%);
  }
  .pull-up {
    line-height: 40px;
    transform: translateY(100%);
  }
  li {
    line-height: 60px;
  }
}
</style>

全部导入

<template>
  <div class="BScroll" ref="BScroll">
    <div class="content">
      <div class="pull-down" v-show="!isLoading">
        {{pullDownMsg}}
      </div>
      <p v-show="isLoading">加载中...</p>
      <ul>
        <li v-for="(item, index) in list" :key="index">{{item}}</li>
      </ul>
      <div class="pull-up" v-show="!isLoading">
        {{pullUpMsg}}
      </div>
      <p v-show="isLoading">加载中...</p>
    </div>
  </div>
</template>

<script>
import BScroll from 'better-scroll'

export default {
  name: 'BScroll',
  data () {
    return {
      bs: null,
      options: {
        // 允许派发滚动事件
        probeType: 1,
        // 允许原生点击事件
        click: true
      },
      threshold: 50,
      pullDownMsg: '下拉刷新',
      pullUpMsg: '上拉加载',
      list: Array.from({ length: 10 }, (v, i) => i),
      total: 20,
      isLoading: false
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    fetchData () {
      return new Promise(resolve => {
        const list = Array.from({ length: 10 }, (v, i) => i + 1)
        setTimeout(() => resolve(list), 1000)
      })
    },
    init () {
      this.bs = new BScroll(this.$refs.BScroll, this.options)

      this.bs.on('scroll', pos => {
        if (pos.y > this.threshold) {
          this.pullDownMsg = '释放开始刷新'
        } else if (pos.y > 0) {
          this.pullDownMsg = '下拉刷新'
        } else if (pos.y < this.bs.maxScrollY - this.threshold) {
          this.pullUpMsg = '释放加载更多'
        } else if (pos.y < this.bs.maxScrollY) {
          this.pullUpMsg = '上拉加载'
        }
        console.log('scroll', pos.y, this.pullDownMsg)
      })

      this.bs.on('touchEnd', async (pos) => {
        if (this.list.length >= this.total) {
          this.pullUpMsg = '我是有底线的'
          return
        }

        if (pos.y > this.threshold) {
          this.isLoading = true
          console.log('pullingDown', pos)
          const list = await this.fetchData()
          this.isLoading = false
          this.list = list
          this.$nextTick(() => this.bs.refresh())
        } else if (pos.y < this.bs.maxScrollY - this.threshold) {
          this.isLoading = true
          console.log('pullingUp', pos)
          const list = await this.fetchData()
          this.isLoading = false
          this.list.push(...list)
          this.$nextTick(() => this.bs.refresh())
        }
      })
    }

  }
}
</script>

<style lang="scss" scoped>
.BScroll {
  height: 500px;
  overflow: hidden;
  .pull-down {
    line-height: 40px;
    transform: translateY(-100%);
  }
  .pull-up {
    line-height: 40px;
    transform: translateY(100%);
  }
  li {
    line-height: 60px;
  }
}
</style>

3.注意

1.滚动区域需要有固定高度
2.滚动区域需要 overflow:hidden
3.局部引入底部会出现无法回弹情况

尾声

从前有一只小鸭子,它整天只会说晚安 ,其他小鸭子就觉得很奇怪啊,于是找它的主人问,为什么这只小鸭子只会说晚安呢?它的主人就说,因为它的名字就叫晚安鸭

晚安鸭,晚安呀

参考链接