美文网首页前端技术
better-scroll遇见vue

better-scroll遇见vue

作者: 前端来入坑 | 来源:发表于2018-12-09 14:52 被阅读1次
    • 介绍better-scroll

    better-scroll 最常见的应用场景是列表滚动,我们来看一下它的 html 结构

    <div class="wrapper">
      <ul class="content">
        <li>...</li>
        <li>...</li>
        ...
      </ul>
      <!-- 这里可以放一些其它的 DOM,但不会影响滚动 -->
    </div>
    

    上面的代码中 better-scroll 是作用在外层 wrapper 容器上的,滚动的部分是 content 元素。这里要注意的是,better-scroll 只处理容器(wrapper)的第一个子元素(content)的滚动,其它的元素都会被忽略。

    最简单的初始化代码如下:

    import BScroll from 'better-scroll'
    let wrapper = document.querySelector('.wrapper')
    let scroll = new BScroll(wrapper)
    
    • better-scroll在vue中的使用

    安装 npm install better-scroll --save

    <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>
    

    Vue.js 提供了我们一个获取 DOM 对象的接口—— vm.$refs。在这里,我们通过了 this.$refs.wrapper访问到了这个 DOM 对象,并且我们在 mounted 这个钩子函数里,this.$nextTick 的回调函数中初始化 better-scroll 。因为这个时候,wrapper 的 DOM 已经渲染了,我们可以正确计算它以及它内层 content 的高度,以确保滚动正常。

    这里的 this.$nextTick 是一个异步函数,为了确保 DOM 已经渲染,感兴趣的同学可以了解一下它的内部实现细节,底层用到了 MutationObserver 或者是 setTimeout(fn, 0)。其实我们在这里把 this.$nextTick 替换成 setTimeout(fn, 20) 也是可以的(20 ms 是一个经验值,每一个 Tick 约为 17 ms),对用户体验而言都是无感知的。

    • better-scroll的事件
    <template>
      <div class="wrapper" ref="wrapper">
        <ul class="content">
          <li v-for="item in data">{{item}}</li>
        </ul>
        <div class="loading-wrapper"></div>
      </div>
    </template>
    <script>
      import BScroll from 'better-scroll'
      export default {
        data() {
          return {
            data: []
          }
        },
        created() {
          this.loadData()
        },
        methods: {
          loadData() {
            requestData().then((res) => {
              this.data = res.data.concat(this.data)
              this.$nextTick(() => {
                if (!this.scroll) {
                  this.scroll = new BScroll(this.$refs.wrapper, {})
                  this.scroll.on('touchend', (pos) => {
                    // 下拉动作
                    if (pos.y > 50) {
                      this.loadData()
                    }
                  })
                } else {
                  this.scroll.refresh()
                }
              })
            })
          }
        }
      }
    </script>
    

    这段代码比之前稍微复杂一些, 当我们在滑动列表松开手指时候, better-scroll 会对外派发一个 touchend 事件,我们监听了这个事件,并且判断了 pos.y > 50(我们把这个行为定义成一次下拉的动作)。如果是下拉的话我们会重新请求数据,并且把新的数据和之前的 data 做一次 concat,也就更新了列表的数据,那么数据的改变就会映射到 DOM 的变化。需要注意的一点,这里我们对 this.scroll 做了判断,如果没有初始化过我们会通过 new BScroll 初始化,并且绑定一些事件,否则我们会调用 this.scroll.refresh 方法重新计算,来确保滚动效果的正常。

    官网https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/#better-scroll%20%E6%98%AF%E4%BB%80%E4%B9%88
    参考https://zhuanlan.zhihu.com/p/27407024

    相关文章

      网友评论

        本文标题:better-scroll遇见vue

        本文链接:https://www.haomeiwen.com/subject/oywhcqtx.html