Vue.js在复杂信息流场景下的实践
Posted 前端之巅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue.js在复杂信息流场景下的实践相关的知识,希望对你有一定的参考价值。
常见的 hybird 页面
-
常见的 UGC 类的 PC 网页
这类页面都会承载着多个信息流列表,本文就针对这类复杂信息流页面进行梳理,给出我在做了无数次这类页面后的最佳实践总结。
你可以查看最终 demo 效果: https://falstack.github.io/vue-hybird-best-practices/
demo 的代码仓库: https://github.com/falstack/vue-hybird-best-practices
切换 Tab 时的渐变动画
-
滑动时的手指跟随
因为这些 feature 能够让我们的页面效果尽可能的接近原生,因此专门把它抽象成一个组件:
我们注意到页面顶部的这个图片轮播组件与 Tab 组件的区别仅仅是:「能否自动滑动」。因此我们在 v-switcher 里增加了几行代码来兼容图片轮播功能。
v-switcher 的实现还兼容了很多场景,可以查看 github 的 readme 来了解。
-
loading(加载中) -
nothing(列表为空) -
error(列表加载出错) -
fetched(已经向服务端发起过请求的列表) noMore(列表已加载完,没有更多了)
除此之外我们还要根据列表的长度在第一屏展示特殊的 loading(通常为骨架屏)或 error (通常为大图),而在非第一屏的情况下展示其它 UI 样式。
当我们点击 Tab 切换到另一个列表的时候,上一个列表的状态要正确的维持,下一个列表和上一个列表的状态要分离开,如果还需要下拉刷新、筛选排序等,如果不抽象一个数据层出来,那这个代码是真的难看,相信经常做这类页面的同学都深有体会。
为了对信息流的数据和状态进行一个完美的管理,我们又提供了另一个组件:
所谓惰性渲染,就是指在列表里只保留视口内的 DOM,视口之外的 DOM 不展示,在列表滚动的时候,我们通过 JS 来计算要渲染哪些 DOM,达到优化内存的目的。
-
无法兼容 better-scroll 仅支持单列的列表,无法支持瀑布流
因此这个库虽然很好,但对我来说它的应用场景“受限”,所以没办法只好自己写了一个:
其实和 vue-virtual-scroll-list 对比区别不是很大,只是我将“滚动”的行为从组件中剥离出去,只保留了滚动的结果,因此使用该组件的时候它需要一个父容器来分发scroll
事件。
支持瀑布流也只是在计算 DOM 位置的时候根据 props 做了不同的 case 处理,都很简单。
但它可以应用在更广的场景中。
至此我们的页面无论是代码整洁度还是性能都有了一定的保障(
v-switcher
针对性能也做了很多优化、vue-flow-render
也是尽可能通过少的计算量来实现的惰性加载)
于是我们就开心的写完代码提交给了测试的同事验收,但发现好像还有点问题?
具体是什么问题呢,相信经常做移动端开发的同学都有遇到过这个问题:-webkit-overflow-scrolling: touch 导致的页面锁死。
遇到这个问题真是难受,网上的解决方法五花八门都达不到效果。
因为毕竟做了很久的前端开发,所以我对这个 bug 是早就知道的,因此在一开始寻找惰性加载组件时就希望能够与 better-scroll 搭配使用,因为 better-scroll 是可以解决页面锁死问题的。
于是我们愉快的使用起了 better-scroll 又提测了。
然后发现又有点不对:
better-scroll 在 android 设备上的体验,真的很不好,特别是当页面里的数据量很大,并且有很多个 tab(需要很多个 better-scroll 实例)的时候。
而且在其他项目中尝试使用 better-scroll 会在复杂场景下(路由切换 + 异步请求等)会导致一些机型(iPhoneX)的偶现 bug。
因此在测试同学的强烈要求下,我们也无法使用 better-scroll 了。
但这个问题还是得解决啊,于是我们在寻找专门解决页面锁死的库,终于是找到了一个:iNoBounce,尝试了一下真的解决了问题。
但怎么说呢,这个库用起来并不怎么舒服,把它加到我们的最佳实践里好像还缺了一些分量,我们需要加强它。
-
我们需要解决 ios 页面锁死的问题。 -
我们需要分发 scroll 事件给 vue-flow-render。 我们有更多的场景需要 onTop、onBottom、onRefresh 等事件
因此我们提供了另一个组件:
至此,我们的「Vue.js 在复杂信息流场景下的最佳实践」所需要的组件都已经给出来了,接下来就简单讲一下为什么要这么做。
虽然这篇文章介绍了四个组件搭配的结果,但并不代表着你需要在所有地方都同时使用它们。
在其他场景的最佳实践下会需要其他组件,这其中有一点是可以肯定的:我们的代码不能杂糅起来,必须要很好的分层,再去组件化。
我相信很多学习 Vue.js 的同学都看过下面这种图:
组件化开发
但在复杂场景下,又有多少人能把代码合理的抽象与组件化呢?
vue-mixin-store 的实现初衷就是因为我之前有一个同事列表从来不写 loading,也不做异常处理,页面代码里到处都是 DOM 操作,我实在是受不了了才写了这么个组件出来。
希望这篇文章能让你的开发变得简单,感谢阅读(记得 star 和遇到问题提 issue 给我)。
解锁 80+ 极客时间课程,全方位提升技术水平和业务能力。扫描图上二维码,或点击“阅读原文”享受七夕特惠
以上是关于Vue.js在复杂信息流场景下的实践的主要内容,如果未能解决你的问题,请参考以下文章