大家好,我是潘Sir,持续分享IT技术,帮你少走弯路。《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容、欢迎关注!
ArkTS拓展了TypeScript,可以结合ArkUI进行渲染控制,是的界面设计具有可编程性。本文简要描述鸿蒙应用开发中的条件渲染和循环渲染。
一、条件渲染
1.1 概述
条件渲染可根据应用的不同状态渲染不同的UI界面,例如前文的开/关灯案例,以及以下的播放/暂停案例,均可使用条件渲染实现。
常见案例:网站的登录和注册模块、商城网站会员价格显示等
1.2 语法
条件渲染的语法如下
if (...){
//UI描述
}else if (...){
//UI描述
}else{
//UI描述
}
1.3 案例
表白案例
typescript
@Entry
@Component
// 条件渲染
struct ConditionPage {
@State isSuc: boolean = true;
build() {
Column({space:20}) {
if (this.isSuc) {
Text('表白成功,O(∩_∩)O')
} else {
Text('继续加油,😔')
}
Button('表白')
.backgroundColor(Color.Green)
.onClick(()=>{
this.isSuc=!this.isSuc
})
}
.width('100%')
.height('100%')
.margin({top:50})
}
}
二、循环渲染
2.1 概述
循环渲染可使用ForEach
语句基于一个数组来快速渲染一个组件列表,例如以下案例中的选项列表就可通过循环渲染实现。
2.2 语法
ForEach
循环渲染的语法如下
ForEach(
arr: any[],
itemGenerator: (item: any, index?: number) => void,
keyGenerator?: (item: any, index?: number) => string
)
各参数的含义如下
- arr
需要进行循环渲染的数据源,必须为数组类型,例如上述案例中的
@State options: string[] = ["苹果", "桃子", "香蕉", "橘子"];
- itemGenerator
组件生成函数,用于为arr
数组中的每个元素创建对应的组件。该函数可接收两个参数,分别是
-
- item:
arr
数组中的数据项 - index(可选):
arr
数组中的数据项的索引
- item:
例如上述案例中的
(item: string) => {
Button(item)
.width(100)
.backgroundColor(Color.Green)
.onClick(() => {
this.answer = item;
})
}
- keyGenerator(可选):
key 生成函数,用于为arr
数组中的每个数据项生成唯一的key。
key的作用
ForEach
在数组发生变化(修改数组元素或者向数组增加或删除元素)时,需要重新渲染组件列表,在重新渲染时,它会尽量复用原来的组件对象,而不是为每个元素都重新创建组件对象。key 的作用就是辅助ForEach
完成组件对象的复用。
具体逻辑如下:
ForEach
在进行初次渲染时,会使用keyGenerator 为数组中的每个元素生成一个唯一的key ,并将key 作为组件对象的标识。当数组发生变化导致ForEach
需要重新渲染时,ForEach
会再次使用keyGenerator 为每个元素重新生成一遍key ,然后ForEach
会检查新生成的key 在上次渲染时是否已经存在,若存在,ForEach
就会认为这个key 对应的数组元素没有发生变化,那它就会直接复用这个key 所对应的组件对象;若不存在,ForEach
就会认为这个key对应的元素发生了变化,或者该元素为新增元素,此时,就会为该元素重新创建一个组件对象。
开发者可以通过keyGenerator 函数自定义key 的生成规则。如果开发者没有定义keyGenerator 函数,则系统会使用默认的key生成函数,即
(item: any, index: number) => { return index + '__' + JSON.stringify(item); }
在某些情况下默认的key 生成函数,会导致界面渲染效率低下,此时可考虑通过keyGenerator函数自定义生成逻辑,例如如下场景
状态变量数组定义如下
@State arr:string[] = ["zhangsan","lisi","wangwu"]
ForEach语句如下
Column(){
ForEach(this.arr,(item)=>{ Text(item) })
}
初次渲染时,每个元素对应的key 依次为0__"zhagnsan"
、1__"lisi"
、2__"wangwu"
。若现有一个操作是向arr
数组头部插入新的元素,例如新元素为wanger ,按照默认的key 生成逻辑,插入新元素之后每个元素的key 就会依次变为0__"wanger"
、1__"zhagnsan"
、2__"lisi"
、3__"wangwu"
,也就是所有元素的key都发生了变化,因此UI界面更新时需要为每个元素都重新创建组件对象,即便原有的元素没有发生变化也无法复用之前的组件,这样一来就导致了性能浪费。此时我们就可以考虑提供第三个参数,如下
Column(){
ForEach(this.arr, (item)=>{ Text(item) }, item => JSON.stringify(item))
}
2.3 案例
爱好列表
@Entry
@Component
// 循环控制
struct LoopPage {
@State likes: string[] = ["唱歌", "跳舞", "学习", "打豆豆"];
@State choose: string = ""; //注意string是小写
build() {
Row() {
Column() {
Text('你喜欢的是:' + this.choose)
ForEach(this.likes, (item) => {
Button(item)
.width(200)
.margin(10)
.onClick(()=>{
this.choose=item
})
})
}
.width('100%')
}
.height('100%')
}
}
《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容,防止迷路,欢迎关注!