分享一个简单的长列表实现方案
发布于 4 年前 作者 gguo 3900 次浏览 来自 分享

一、我们知道小程序针对长列表有两个硬杠杠,一旦越界直接给白屏:

1、setData的数组数据不能超过1M。

2、列表DOM数不能太多,具体数据未知。

官方这样处理也不无道理,太长了本身性能确实也有问题。所以长列表一定要人为干预处理,不处理一直往下拉肯定是不行的。

二、目前主流的处理方法有三种:

1、二维数组,就是把数据改为二维的,每一个分页数据作为一个一维数组的元素。只是这样处理,只解决了setData的问题,DOM的问题并未解决。并且把本来是一维的数据强行二维化,在很多逻辑处理上变得复杂。

2、官方提供了一个扩展组件recycle-view,但它要求item等高。https://developers.weixin.qq.com/miniprogram/dev/extended/component-plus/recycle-view.html,存在局限性。

3、自行搭建骨架屏,类似于方案2的自研版本。实现成本比较高。

三、进入正题,介绍方案,由于足够简单,我只说思路,代码示例就不放了,如有疑问可以留言回复。

1、思路:只保留最新的n页数据进行setData,每新加载一页数据,就舍弃最前面一页的数据。同时把第1页的数据保存起来,监听onPageScroll,如果发现用户拉回到了页面顶部,则舍弃所有数据,把第1页的数据setData回来。

2、举个例子:假设n=5,那么当加载了第6页数据时,第6页数据合并到数组尾部,把数组头部的第1页数据去掉,让setData的数据始终保持5页。这里有个细节要处理好,就是去除数据的时候先setData一次,新数据加载合并后,再setData一次,这样可以保证用户的scrollTop不会走位,停留在最新一条数据那个位置。

3、这个方案足够简单通用,也存在一些弊端,看你实际项目中能否接受,主要有两个问题:a、用户如果从尾部又慢慢的逐条拉回到顶部,到达顶部时会出现突然跳跃,直接回到第一页的数据。b、去除数据的setData操作时,存在一定程度的闪屏现象。

4、适用范围:比较适合信息处理类应用。这类应用,往往头几屏内容就能找到信息,比较少会拉很长。而且往往都是直接回到顶部,不会逐条翻回去。所以这类应用只要保证不出白屏,一些不太碰到的细节体验可以降低要求。信息浏览类应用,比如新闻应用,就不一定合适了。

1 回复

uniapp上发现的这个,貌似还不错

data: {  
    listData: []  
},  
onReachBottom() { //上拉加载  
    // 通过长度获取下一次渲染的索引  
    let index = this.data.listData.length;  
    let newData = {}; //新变更数据  
    Api.getNews().forEach((item) => {  
        newData['listData[' + (index++) + ']'] = item //赋值,索引递增  
    })   
    this.setData(newData) //增量数据,发送数据到视图层  
}
回到顶部