【HarmonyOS (ArkTS) 基础渲染指南第7天】:条件渲染与循环渲染
·
1. 条件渲染 (Conditional Rendering)
条件渲染允许根据状态变量的值,动态决定显示哪些组件。这在处理登录状态、权限控制或不同数据展示场景时非常有用。
1.1 基础语法
在 ArkTS 中,支持标准的 if/else 语句块直接写在 build() 方法内部。
核心规则:
if、else if和else必须紧跟在组件容器(如Column,Row)内部。- 每个分支必须返回有效的组件或组件树。
- 条件判断通常基于组件的状态变量(使用
@State装饰),但在简单示例中也可以使用普通变量(注意:普通变量变化不会触发 UI 刷新,实际开发中建议使用@State)。
1.2 示例代码解析
// 定义状态变量,初始值为 3
@State num: number = 3;
@Entry
@Component
struct Index {
build() {
Column({ space: 10 }) { // 添加间距使布局更美观
Text('当前数字:' + this.num)
.fontSize(20)
.fontWeight(FontWeight.Bold)
// 条件渲染区域
if (this.num === 1) {
Text('文本 1')
.fontSize(30)
.fontColor(Color.Red)
} else if (this.num === 2) {
Text('文本 2')
.fontSize(30)
.fontColor(Color.Blue)
} else {
// 涵盖 num === 3 及其他所有情况
Text('文本 else (默认显示)')
.fontSize(30)
.fontColor(Color.Green)
}
// 模拟交互按钮(仅用于演示状态变化)
Row({ space: 10 }) {
Button('设为 1').onClick(() => this.num = 1)
Button('设为 2').onClick(() => this.num = 2)
Button('设为 3').onClick(() => this.num = 3)
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
1.3 运行结果说明
- 当
num为 1 时:界面显示红色的“文本 1”。 - 当
num为 2 时:界面显示蓝色的“文本 2”。 - 当
num为 3 (或其他值) 时:界面显示绿色的“文本 else (默认显示)”。 - 动态性:由于使用了
@State,点击按钮修改变量时,UI 会自动刷新,无需手动操作 DOM。
2. 循环渲染 (Loop Rendering)
循环渲染用于将数组数据映射为一系列相同的组件结构。在 ArkTS 中,主要通过 ForEach 接口实现。
2.1 基础语法
ForEach 需要三个参数(第三个可选):
- 数组:要遍历的数据源。
- 生成函数:
(item, index) => { ... },定义如何为每个元素生成组件。 - 键生成函数 (可选但推荐):
(item) => uniqueKey,用于提高列表更新性能。
重要提示:
ForEach只能作为容器的直接子节点(如Column,Row,Grid等)。- 在
ForEach生成的闭包内,不能直接使用外层的this上下文中的非静态成员,除非通过箭头函数正确绑定。
2.2 示例代码解析
// 定义数据源
names: string[] = ['大壮', '中壮', '小壮'];
@Entry
@Component
struct Index {
build() {
Column({ space: 15 }) {
Text('家庭成员列表')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
// 循环渲染区域
ForEach(this.names, (item: string, index: number) => {
Row() {
Text(`${index + 1}. ${item}`)
.fontSize(18)
.fontColor('#333333')
// 添加一个简单的图标或装饰
Text('👤')
.fontSize(20)
.margin({ left: 10 })
}
.width('90%')
.padding(15)
.backgroundColor('#F5F5F5')
.borderRadius(10)
.justifyContent(FlexAlign.SpaceBetween)
}, (item: string) => item); // 使用名字作为唯一键 (假设名字不重复)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Start)
.padding(20)
}
}
2.3 运行结果说明
- 界面会垂直排列三个卡片式的行(Row)。
- 第一行显示:1. 大壮 👤
- 第二行显示:2. 中壮 👤
- 第三行显示:3. 小壮 👤
- 每个条目都有独立的背景色、圆角和内边距,看起来像一个整齐的列表。
3. 进阶技巧与注意事项
3.1 状态驱动视图
在实际开发中,务必使用 @State、@Prop 或 @Link 装饰变量。
- 错误做法:
let num: number = 3(修改后界面不会变)。 - 正确做法:
@State num: number = 3(修改后界面自动重组)。
3.2 ForEach 的键值 (Key)
虽然示例中省略了第三个参数,但在生产环境中,强烈建议提供键值生成函数。
- 作用:帮助框架识别哪些数据项被添加、删除或移动,从而只更新受影响的组件,而不是重绘整个列表。
- 要求:键值必须是字符串或数字,且在数组中唯一。
// 推荐写法
ForEach(items, (item) => {
// ...
}, (item) => item.id); // 使用唯一 ID 作为 key
3.3 嵌套使用
条件渲染和循环渲染可以嵌套使用。例如:先判断列表是否为空,如果不为空则循环渲染,否则显示“暂无数据”。
if (this.names.length > 0) {
ForEach(this.names, (item) => {
Text(item)
})
} else {
Text('暂无数据')
.fontColor(Color.Gray)
}
总结
| 特性 | 条件渲染 (if/else) |
循环渲染 (ForEach) |
|---|---|---|
| 用途 | 根据布尔值或枚举值显示不同内容 | 根据数组长度批量生成相同结构的组件 |
| 语法位置 | 直接在 build() 或容器内 |
必须在容器内作为直接子节点 |
| 性能关键 | 避免复杂的逻辑判断 | 必须提供唯一的 key 以优化复用 |
| 典型场景 | 登录/未登录视图、空状态页 | 新闻列表、聊天消息、商品网格 |
更多推荐



所有评论(0)