鸿蒙学习实战之路-ArkTS 条件渲染\_ifelse 使用指南
害,最近好多刚开始学鸿蒙开发的朋友问我:“西兰花啊,我以前写前端页面的时候,可以用 if else 控制页面内容,在鸿蒙里是不是也可以?还是要写很多复杂的代码?” 害,这问题可问对人了!今天这篇,我就手把手带你从零开始搞定,保证你 5 分钟就能学会~
鸿蒙学习实战之路-ArkTS 条件渲染_ifelse 使用指南
害,最近好多刚开始学鸿蒙开发的朋友问我:“西兰花啊,我以前写前端页面的时候,可以用 if else 控制页面内容,在鸿蒙里是不是也可以?还是要写很多复杂的代码?” 害,这问题可问对人了!
今天这篇,我就手把手带你从零开始搞定 ArkTS 条件渲染,保证你 5 分钟就能学会~
这是个啥?
ArkUI 通过自定义组件的 build() 函数和 @Builder 装饰器中的声明式 UI 描述语句构建相应的 UI。在声明式描述语句中开发者除了使用系统组件外,还可以使用渲染控制语句来辅助 UI 的构建,这些渲染控制语句包括控制组件是否显示的条件渲染语句,基于数组数据快速生成组件的循环渲染语句,针对大数据量场景的数据懒加载语句,针对混合模式开发的组件渲染语句。
简单来说,条件渲染就是根据条件动态显示不同的 UI 内容,这就像 Vue 里的 v-if 指令,或者 React 里的三元表达式一样~
这玩意儿能干什么?
条件渲染能帮你实现很多实用场景:
- 登录状态控制:登录后显示用户信息,未登录显示登录按钮
- 数据加载状态:加载中显示 Loading,成功后显示数据,失败显示错误信息
- 权限控制:根据用户权限显示不同的功能按钮
- 响应式界面:根据屏幕尺寸或设备类型显示不同布局
- 购物车状态:有商品时显示购物车,空购物车时显示提示
🥦 西兰花小贴士:
条件渲染非常适合做状态管理,比如 loading、success、error 三种状态的切换,比用 visibility 或 display 属性更灵活~
使用规则你得知道
在开始写代码之前,这些规则你得先了解:
| 规则类别 | 具体说明 |
|---|---|
| 语法支持 | 支持 if、else 和 else if 完整条件语句 |
| 条件变量 | 可使用状态变量(值改变时实时渲染 UI),可使用常规变量(值改变不会触发 UI 更新) |
| 容器限制 | 允许在容器组件内使用,条件渲染对组件父子关系是"透明"的 |
| 构建函数规则 | 每个分支内部的构建函数必须创建一个或多个组件,空构建函数会产生语法错误 |
🥦 西兰花警告:
注意了!条件分支里的构建函数不能是空的,必须至少创建一个组件。我之前写了个 if (show) { } 结果编译报错,整了半天才发现…(┓( ´∀` )┏)
跟着我做,3 种用法搞定
1. 基础 if 条件渲染
最简单的情况,就是根据一个变量显示不同的文本或组件:
@Entry
@Component
struct BasicIfRendering {
@State count: number = 0;
build() {
Column() {
Text(`当前计数: ${this.count}`)
.fontSize(18)
// 条件渲染核心代码
if (this.count > 0) {
Text(`计数为正数`)
.fontColor(Color.Green)
.fontSize(16)
} else if (this.count < 0) {
Text(`计数为负数`)
.fontColor(Color.Red)
.fontSize(16)
} else {
Text(`计数为零`)
.fontColor(Color.Gray)
.fontSize(16)
}
Button('增加计数')
.onClick(() => this.count++)
.margin(5)
Button('减少计数')
.onClick(() => this.count--)
.margin(5)
}
.width('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
工作原理:
- 初始渲染时,if 语句执行构建函数并添加相应组件
- 当
count状态变量变化时,条件语句重新评估 - 分支变化时,旧组件被移除,新组件被创建并添加到父组件
这就像 Vue 的 v-if 一样,条件为真时创建组件,为假时销毁组件~
2. 状态管理问题与解决方案
这里有个坑需要注意!当条件切换时,子组件的状态会被重置:
// 子组件定义
@Component
struct CounterView {
@State counter: number = 0;
label: string = 'unknown';
build() {
Column({ space: 10 }) {
Text(this.label)
.fontSize(16)
Button(`计数器: ${this.counter} +1`)
.onClick(() => this.counter++)
.width('100%')
}
.margin(10)
.padding(15)
.border({ width: 1, color: Color.Gray })
.borderRadius(5)
}
}
// 父组件使用条件渲染
@Entry
@Component
struct IfElseStateManagement {
@State toggle: boolean = true;
build() {
Column() {
// 条件渲染子组件
if (this.toggle) {
CounterView({ label: '正向计数器' })
} else {
CounterView({ label: '反向计数器' })
}
Button(`切换状态 (当前: ${this.toggle})`)
.onClick(() => this.toggle = !this.toggle)
.margin(10)
}
.width('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
问题所在:
- 当
toggle状态变化时,旧的CounterView实例会被删除,创建新的实例 - 新旧
CounterView是同一自定义组件的不同实例,状态不会共享 - 所以每次切换都会重置计数
🥦 西兰花警告:
这是条件渲染的一个常见坑!很多人以为子组件状态会保留,结果发现切换后数据丢失了…解决方法就是状态提升~
解决方案 - 状态提升:
@Component
struct CounterView {
@Link counter: number; // 使用@Link引用父组件状态
label: string = 'unknown';
build() {
Column({ space: 10 }) {
Text(this.label)
.fontSize(16)
Button(`计数器: ${this.counter} +1`)
.onClick(() => this.counter++)
.width('100%')
}
.margin(10)
.padding(15)
.border({ width: 1, color: Color.Gray })
.borderRadius(5)
}
}
@Entry
@Component
struct StatePreservationExample {
@State toggle: boolean = true;
@State counter: number = 0; // 状态提升至父组件
build() {
Column() {
if (this.toggle) {
CounterView({
label: '正向计数器',
counter: $counter // 传递状态引用
})
} else {
CounterView({
label: '反向计数器',
counter: $counter // 共享同一状态
})
}
Button(`切换状态 (当前: ${this.toggle})`)
.onClick(() => this.toggle = !this.toggle)
.margin(10)
}
.width('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
这样就能在切换条件时保持状态不变啦~
3. 嵌套条件渲染
复杂业务逻辑经常需要嵌套 if 语句:
@Entry
@Component
struct NestedIfExample {
@State toggleOuter: boolean = false;
@State toggleInner: boolean = false;
build() {
Column({ space: 15 }) {
Text('条件渲染嵌套示例')
.fontSize(20)
.fontWeight(FontWeight.Bold)
// 外层条件
if (this.toggleOuter) {
Column({ space: 10 }) {
Text('外层条件为真')
.fontSize(18)
.backgroundColor('#aaffaa')
.padding(10)
// 内层条件
if (this.toggleInner) {
Text('内层条件为真')
.fontSize(16)
.backgroundColor('#00aaaa')
.padding(8)
} else {
Text('内层条件为假')
.fontSize(16)
.backgroundColor('#aaaaff')
.padding(8)
}
}
} else {
Column({ space: 10 }) {
Text('外层条件为假')
.fontSize(18)
.backgroundColor('#ffaaaa')
.padding(10)
// 内层条件
if (this.toggleInner) {
Text('内层条件为真')
.fontSize(16)
.backgroundColor('#00aaaa')
.padding(8)
} else {
Text('内层条件为假')
.fontSize(16)
.backgroundColor('#aaaaff')
.padding(8)
}
}
}
Row({ space: 10 }) {
Button('切换外层条件')
.onClick(() => this.toggleOuter = !this.toggleOuter)
Button('切换内层条件')
.onClick(() => this.toggleInner = !this.toggleInner)
}
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center)
}
}
🥦 西兰花小贴士:
嵌套条件渲染虽然强大,但别嵌套太深!超过 3 层就考虑把逻辑拆分到函数或计算属性里,这样代码更清晰~
常见坑与解决方案
1. 状态丢失问题
问题:条件分支切换时,子组件状态被重置
原因:分支切换会创建新的组件实例,原实例及其状态被销毁
解决方案:
- 将状态提升至父组件
- 使用
@Link或@Provide/@Consume在组件间共享状态 - 对于复杂状态,考虑使用状态管理库
2. 性能优化
问题:频繁切换条件导致性能问题
解决方案:
- 减少条件渲染层级,避免过度嵌套
- 对于简单显示/隐藏需求,考虑使用
Visibility属性 - 避免在条件渲染中创建复杂组件树
3. 容器组件限制
问题:在特定容器中使用条件渲染报错
原因:某些容器组件对子组件类型有严格限制
解决方案:
- 确保条件渲染语句内创建的组件符合容器要求
- 例如:
Grid容器内只能使用GridItem组件
🥦 西兰花警告:
记住!Grid 容器内的条件渲染语句只能使用 GridItem 组件,如果你用了其他组件,编译时会报错…别问我怎么知道的 T_T
更新机制你得懂
当 if、else if 后的条件语句中使用的状态变量值改变时,条件渲染会按以下步骤更新:
- 条件评估:重新计算 if 和 else if 的条件表达式
- 分支判断:
- 若分支未变化,不执行后续步骤
- 若分支变化,则执行步骤 3 和 4
- 移除旧组件:删除此前构建的所有子组件
- 创建新组件:执行新分支的构造函数,添加生成的子组件到父容器中
注意:条件表达式中可包含 Typescript 表达式,但构造函数中的表达式不得更改应用程序状态
最佳实践
-
状态管理:
- 避免在条件分支中创建复杂状态
- 共享状态应放在条件分支外部的父组件中
-
代码组织:
- 保持条件分支代码简洁,复杂逻辑应提取为独立函数或组件
- 条件表达式应简单明了,复杂条件可封装为计算属性
-
性能考量:
- 避免不必要的条件判断
- 对于大型列表,考虑使用
LazyForEach结合条件渲染
-
可读性:
- 对复杂条件渲染添加注释
- 保持分支内组件结构一致,便于维护
下一步
👉 预告:《ArkTS 循环渲染_forEach 使用指南》
📚 推荐资料:
- 官方条件渲染文档:ArkTS 条件渲染_ifelse 使用指南
- 官方入门教程:开发者学堂
- ArkUI 渲染控制概览:渲染控制语句
我是盐焗西兰花,
不教理论,只给你能跑的代码和避坑指南。
下期见!🥦
更多推荐

所有评论(0)