vue项目中使用better-scroll摘录的文章(上)
列表滚动的实现
<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 。
异步数据的处理<templat
<div class="wrapper" ref="wrapper">
<ul class="content"> <li v-for="item in data">{{item}}</li> </ul> </div> </template> <script> import BScroll from 'better-scroll' export default { data() { return { data: [] } }, created() { requestData().then((res) => { this.data = res.data this.$nextTick(() => { this.scroll = new Bscroll(this.$refs.wrapper, {}) }) }) } } </script>
这里的 requestData 是伪代码,作用就是发起一个 http 请求从服务端获取数据,并且这个函数返回的是一个 promise(实际项目中我们可能会用 axios 或者 vue-resource)。我们获取到数据的后,需要通过异步的方式再去初始化 better-scroll,因为 Vue 是数据驱动的,
Vue 数据发生变化(this.data = res.data)到页面重新渲染是一个异步的过程,我们的初始化时机是要在 DOM 重新渲染后,所以这里用到了 this.$nextTick。为什么这里在 created 这个钩子函数里请求数据而不是放到 mounted 的钩子函数里?
因为 requestData 是发送一个网络请求,这是一个异步过程,当拿到响应数据的时候,Vue 的 DOM 早就已经渲染好了,但是数据改变 —> DOM 重新渲染仍然是一个异步过程,所以即使在我们拿到数据后,也要异步初始化 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://zhuanlan.zhihu.com/p/27407024