ArkTS “一篇带你读懂ForEach和LazyForEach”【小白拓展】
文章目录
前言
列表是应用开发中最常见的一类开发场景,它可以将杂乱的信息整理成有规律、易于理解和操作的形式,便于用户查找和获取所需要的信息。
在现有的较成熟ArkTs组件中的,推荐大家使用的列表渲染接口是ForEach和LazyForEach。
一、原理介绍
HarmonyOS应用框架为容器类组件的数据加载和渲染提供了2种方式。
方式一,循环渲染
通过循环渲染(ForEach)从数组中获取数据,并为每个数据项创建相应的组件,可减少代码复杂度。
代码如下(示例)详解可以看上一篇:
ForEach(
arr: any[],
itemGenerator: (item: any, index?: number) => void,
keyGenerator?: (item: any, index?: number) => string
)
方式二,数据懒加载
通过数据懒加载(LazyForEach)从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。
使用步骤如下(重点详解):
DataSource: Data<string>=new Data<string>()
LazyForEach(
dataSource: DataSource, (这里要求数据源一定要实现IDataSource接口)
itemGenerator: (item: any) => void,
keyGenerator?: (item: any) => string //可省
): void
class Data implements IDataSource{
**//我们使用需要自己创建**
private originArr:string[]=[] //用来存储数据
private listeners:DataChangeListener[] = [] //用来存储监听
//自定义添加数据方法
addData(data:string[]){
let indexs=this.totalCount()
this.originArr.push(...data)
this.listeners.forEach(listener=>listener.onDataAdd(indexs))
}
**//IDataSource内置方法**
totalCount(): number {
return this.originArr.length //返回数据长度
};
getData(index: number): T{
return this.originArr[index] //返回索引值index对应的数据
};
//注册 数据改变的监听器
registerDataChangeListener(listener: DataChangeListener): void{
//把注册的监听器放入列表
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
};
//注销 数据改变的监听器
unregisterDataChangeListener(listener: DataChangeListener): void{
//把已经注册的监听器从列表移除
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
};
}
//下面是DataChangeListener数据变化监听器 内置方法我们可能会用到的
interface DataChangeListener {
onDataReloaded(): void; //通知组件重新加载所有数据
onDataAdd(index: number): void; //通知组件index的位置有数据添加。
onDataMove(from: number, to: number): void; //通知组件数据有移动。将from和to位置的数据进行交换。
onDataDelete(index: number): void; //通知组件删除index位置的数据并刷新LazyForEach的展示内容。
onDataChange(index: number): void; //通知组件index的位置有数据有变化。
}
二、ForEach是怎么实现渲染的?
从华为文档我们可知
- 从列表数据源 一次性加载全量 数据。
- 为列表数据的每一个元素都创建对应的组件,并全部挂载在组件树上。即,ForEach遍历多少个列表元素,就创建多少个ListItem组件节点并依次挂载在List组件树根节点上。
- 列表内容显示时,只渲染屏幕可视区内的ListItem组件,可视区外的ListItem组件滑动进入屏幕内时,因为已经完成了数据加载和组件创建挂载,直接渲染即可。
在数据量大时会非常耗时,会导致页面启动时间过长、过多占用内存。在系统处于高负载的情况下,更容易出现性能问题,极限情况下甚至会导致应用异常退出。
所以,ForEach适合少量数据渲染
三、LazyForEach是怎么实现渲染的?
- LazyForEach会根据屏幕可视区能够容纳显示的组件数量按需加载数据。
- 当可视区外的组件需要在屏幕内显示时,需要从头完成数据加载、组件创建、挂载组件树这一过程,直至渲染到屏幕上。
概括来说就是,按需加载
针对列表数据量大、列表组件复杂的场景,减少了页面首次启动时一次性加载数据的时间消耗,减少了内存峰值,优化了性能。
我们该怎么选择他们呢
ForEach | 列表数据较少,数据一次性全量加载不是性能瓶颈时 |
---|---|
LazyForEach | 列表数据较长,一次性加载所有的列表数据创建、渲染页面产生性能瓶颈时 |
四、值得注意的使用小tips
1.关于ForEach
ForEach在下列容器组件 List、Grid、Swiper以及WaterFlow 内使用的时候,不要与LazyForEach 混用。
2.关于LazyForEach
LazyForEach必须在容器组件内使用,仅有 List、Grid、Swiper 以及 WaterFlow 组件支持数据懒加载
总结
以上就是今天要讲的内容,请大家注意LazyForEach的使用,较为复杂。具体的大家有疑问可以留言。