Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello uni-app x
提交
8a973878
H
hello uni-app x
项目概览
DCloud
/
hello uni-app x
通知
5995
Star
90
Fork
162
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
18
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-app x
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
18
Issue
18
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
8a973878
编写于
3月 28, 2024
作者:
雪洛
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 优化部分场景下自行实现长列表的性能
上级
010e98f7
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
105 addition
and
2 deletion
+105
-2
pages/template/custom-long-list/README.md
pages/template/custom-long-list/README.md
+82
-0
pages/template/custom-long-list/custom-list-view.uvue
pages/template/custom-long-list/custom-list-view.uvue
+23
-2
未找到文件。
pages/template/custom-long-list/README.md
0 → 100644
浏览文件 @
8a973878
## 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
<
template
>
<uni-recycle-view
style=
"flex: 1;"
:list=
"list"
>
<template
v-slot:default=
"
{items}">
<uni-recycle-item
class=
"item"
v-for=
"item in (items as Item[])"
:item=
"item"
:key=
"item.id"
>
<view
class=
"item-wrapper"
>
<view
class=
"name"
><text
style=
"font-size: 14px;"
>
{{
item
.
name
}}
</text></view>
<view
class=
"info"
><text
style=
"font-size: 12px; color: #999999;"
>
{{
item
.
info
}}
</text></view>
</view>
</uni-recycle-item>
</
template
>
</uni-recycle-view>
</template>
<
script
>
type
Item
=
{
id
:
number
name
:
string
info
:
string
}
export
default
{
data
()
{
return
{
list
:
[]
as
Item
[]
}
},
created
()
{
for
(
let
i
=
0
;
i
<
2000
;
i
++
)
{
this
.
list
.
push
({
id
:
i
,
name
:
`Wifi_`
+
i
,
info
:
`信号强度: -
${(
Math
.
floor
(
Math
.
random
()
*
60
)
+
40
)}
db, 安全性: WPA/WPA2/WPA3-Personal`
}
as
Item
)
}
}
}
</
script
>
```
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,会影响滚动位置的计算
pages/template/custom-long-list/custom-list-view.uvue
浏览文件 @
8a973878
...
@@ -51,6 +51,7 @@
...
@@ -51,6 +51,7 @@
hasDefaultSize: false,
hasDefaultSize: false,
defaultItemSize: 40,
defaultItemSize: 40,
lastScrollTop: 0,
lastScrollTop: 0,
rearrangeQueue: [] as number[]
};
};
},
},
provide() {
provide() {
...
@@ -84,9 +85,29 @@
...
@@ -84,9 +85,29 @@
const scrollTop = e.detail.scrollTop
const scrollTop = e.detail.scrollTop
this.lastScrollTop = 0
this.lastScrollTop = 0
if (scrollTop < this.offsetThreshold[1] || scrollTop > this.offsetThreshold[2]) {
if (scrollTop < this.offsetThreshold[1] || scrollTop > this.offsetThreshold[2]) {
this.
rearrang
e(scrollTop)
this.
queu
e(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) {
rearrange(scrollTop : number) {
this.offsetThreshold[0] = Math.max(scrollTop - this.scrollElementHeight * 5, 0)
this.offsetThreshold[0] = Math.max(scrollTop - this.scrollElementHeight * 5, 0)
this.offsetThreshold[1] = Math.max(scrollTop - this.scrollElementHeight * 3, 0)
this.offsetThreshold[1] = Math.max(scrollTop - this.scrollElementHeight * 3, 0)
...
@@ -119,4 +140,4 @@
...
@@ -119,4 +140,4 @@
<style>
<style>
</style>
</style>
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录