diff --git a/pages/template/custom-long-list/README.md b/pages/template/custom-long-list/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2fb5433cc7cbba41666fd1e34667c64357af0626 --- /dev/null +++ b/pages/template/custom-long-list/README.md @@ -0,0 +1,82 @@ +## uni-recycle-view【TODO 名称待定,由于使用uni-开头应避免和内置组件冲突,比如uni-list和list组件是冲突的】 + +::: tip 组件名:uni-recycle-view +> 代码块: `uRecycleView`、`uRecycleItem` +【TODO 链接待补充】 +[点击下载&安装]() +::: + +uni-recycle-view 组件用于在展示超长列表时优化内存占用以及性能。不同于uni-app list-view组件,uni-recycle-view组件不会对所有数据循环创建VNode。适用于仅使用一个for循环创建所有列表项的场景。 + +### 基本用法 + +```vue + + + +``` + +uni-recycle-view组件传入通过绑定list属性`:list="list"`传入含所有数据的列表。经过组件内部计算,由作用域插槽返回真实要渲染的部分数据`v-slot:default="{items}"`。最终仅需渲染items而不是list,从而节省了大量的计算消耗及内存占用。 + +### 属性及事件 + +|属性名 |类型 |默认值 |说明 | +|:-: |:-: |:-: |:-: | +|list |any[]| [] |列表所有数据 | +|其他 |- |- |其余属性及事件会透传给内部的scroll-view组件,参考: [scroll-view组件](https://doc.dcloud.net.cn/uni-app-x/component/scroll-view.html) | + + +## uni-recycle-item + +uni-recycle-item用于渲染uni-recycle-view筛选出的用于展示的数据。 + +### 属性及事件 + +|属性名 |类型 |默认值 |说明 | +|:-: |:-: |:-: |:-: | +|item |any | - |当前组件渲染的列表项 | + +## 注意事项 + +- uni-recycle-view和uni-recycle-item必须搭配使用 +- uni-recycle-view仅渲染滚动容器当前屏及上下5屏的内容 + +## 已知问题 + +- 不支持设置初始滚动位置 +- 容器大小变动时未刷新缓存的子元素大小,可能导致滚动过程中出现跳动 +- 列表数据内每一项不可以是基础类型 +- uni-recycle-item不要设置margin,会影响滚动位置的计算 diff --git a/pages/template/custom-long-list/custom-list-view.uvue b/pages/template/custom-long-list/custom-list-view.uvue index 40677eb24e182aadd26296a2726a26e3d3c8aab4..d0438333e1d71f71c907de09087a579c7675d2d7 100644 --- a/pages/template/custom-long-list/custom-list-view.uvue +++ b/pages/template/custom-long-list/custom-list-view.uvue @@ -51,6 +51,7 @@ hasDefaultSize: false, defaultItemSize: 40, lastScrollTop: 0, + rearrangeQueue: [] as number[] }; }, provide() { @@ -84,9 +85,29 @@ const scrollTop = e.detail.scrollTop this.lastScrollTop = 0 if (scrollTop < this.offsetThreshold[1] || scrollTop > this.offsetThreshold[2]) { - this.rearrange(scrollTop) + this.queue(scrollTop) } }, + queue(scrollTop : number) { + /* + * rearrange内为大量同步逻辑,在上次rearrange未执行完毕的情况下将后续多个rearrange合并成一次执行,即仅执行最后一次 + * 由于滚动机制差异,此优化仅在web端才有意义。 + * 如何测试:push后console.log(this.rearrangeQueue.length) 输出结果大于1时触发优化 + */ + this.rearrangeQueue.push(scrollTop) + setTimeout(() => { + this.flush() + }, 1) + }, + flush() { + const queueLength = this.rearrangeQueue.length + if (queueLength === 0) { + return + } + const lastScrollTop = this.rearrangeQueue[queueLength - 1] + this.rearrange(lastScrollTop) + this.rearrangeQueue = [] as number[] + }, rearrange(scrollTop : number) { this.offsetThreshold[0] = Math.max(scrollTop - this.scrollElementHeight * 5, 0) this.offsetThreshold[1] = Math.max(scrollTop - this.scrollElementHeight * 3, 0) @@ -119,4 +140,4 @@ \ No newline at end of file +