Vue.js实现无限加载与分页功能开发[better-scroll]

https://www.jb51.net/article/96373.htm
https://www.imooc.com/article/18232
Vue.js实现无限加载与分页功能开发[better-scroll]_第1张图片
需求分析

当一个页面中信息量过大时(例如一个新闻列表中有200条新闻需要展示),就会产生问题,例如:

》数据量过大,影响加载速度

》用户体验差,很难定位到之前自己看过的某篇文章

》扩展性差,如果200条变为2000条或者更多

所以常见的解决思路就是至底时加载数据或者分页展示。无限加载的实现过程类似于:

1.ajax类方法获取数据

2.数据存入本地数组

3.数组中的每条数据对应插入一个HTML模板片段中

4.将HTML片段append到节点中

前端分页的实现过程类似于:

1.ajax类方法获取数据

2.数据替换本地数组

3.数组中的每条数据对应插入一个HTML模板片段中

4.清空节点后将HTML片段append到节点中

上拉无限加载示例:https://www.jianshu.com/p/84ed9ac7ae97


better-scroll中文文档:
https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/#滚动原理

英文GitHub文档:https://github.com/ustbhuangyi/better-scroll

script挂载 示例:https://codepen.io/cklwblove/pen/EOgrER?editors=1111

  • ...
  • ...
  • ...
var bs = new BScroll('.wrapper');

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

这里的 this. n e x t T i c k 是 一 个 异 步 函 数 , 为 了 确 保 D O M 已 经 渲 染 , 底 层 用 到 了 M u t a t i o n O b s e r v e r 或 者 是 s e t T i m e o u t ( f n , 0 ) 。 其 实 我 们 在 这 里 把 t h i s . nextTick 是一个异步函数,为了确保 DOM 已经渲染,底层用到了 MutationObserver 或者是 setTimeout(fn, 0)。其实我们在这里把 this. nextTickDOMMutationObserversetTimeout(fn,0)this.nextTick 替换成 setTimeout(fn, 20) 也是可以的(20 ms 是一个经验值,每一个 Tick 约为 17 ms),对用户体验而言都是无感知的。

异步数据的处理
在我们的实际工作中,列表的数据往往都是异步获取的,因此我们初始化 better-scroll 的时机需要在数据获取后,代码如下:



这里的 requestData 是伪代码,作用就是发起一个 http 请求从服务端获取数据,并且这个函数返回的是一个 promise(实际项目中我们可能会用 axios 或者 vue-resource)。我们获取到数据的后,需要通过异步的方式再去初始化 better-scroll,因为 Vue 是数据驱动的, Vue 数据发生变化(this.data = res.data)到页面重新渲染是一个异步的过程,我们的初始化时机是要在 DOM 重新渲染后,所以这里用到了 this.$nextTick,当然替换成 setTimeout(fn, 20) 也是可以的。

为什么这里在 created 这个钩子函数里请求数据而不是放到 mounted 的钩子函数里?因为 requestData 是发送一个网络请求,这是一个异步过程,当拿到响应数据的时候,Vue 的 DOM 早就已经渲染好了,但是数据改变 —> DOM 重新渲染仍然是一个异步过程,所以即使在我们拿到数据后,也要异步初始化 better-scroll。

用 better-scroll 配合 Vue 实现下拉加载功能
源码:



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

这里,我们就通过 better-scroll 配合 Vue,实现了列表的下拉刷新功能,上拉加载也是类似的套路,一切看上去都是 ok 的。但是,我们发现这里写了大量命令式的代码(这一点不是 Vue.js 推荐的),如果有很多类似滚动的组件,我们就需要写很多类似的命令式且重复性的代码,而且我们把数据请求和 better-scroll 也做了强耦合,这些对于一个追求编程逼格的人来说,就不 ok 了。

作者:ustbhuangyi
链接:https://www.imooc.com/article/18232
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作

你可能感兴趣的:(vue)