一、引言

在鸿蒙应用开发中,条件渲染是一项基础且强大的功能。它允许开发者根据应用状态(如用户输入、数据变化、设备条件等)动态地决定界面上显示哪些内容。简单来说,就是“满足某个条件,才渲染对应的UI组件”。

本文将以一个生动直观的红绿灯切换为例,带你从零开始,深入理解鸿蒙ArkTS中条件渲染的语法、核心用法以及需要注意的陷阱。

二、项目目标与效果预览

我们将创建一个简单的红绿灯模拟应用。

  • 初始状态:红灯亮起,显示“停”。
  • 用户交互:点击“切换信号”按钮。
  • 动态效果:信号灯会在 红(停) -> 绿(行) -> 黄(等) 三者之间循环切换。

通过这个例子,你将清晰地看到if/else三元表达式这两种条件渲染语法如何控制UI的显示与隐藏。

三、基础准备:创建状态变量

所有条件渲染都依赖于状态变量。状态变量的变化会驱动UI重新渲染。

// 在组件的struct中声明一个状态变量
@State count: number = 0;

这里,我们创建了一个名为count的状态变量,初始值为0。我们将用count的值(0, 1, 2)来分别代表红灯、绿灯和黄灯。

四、条件渲染核心语法一:@Builder 与 if/else

鸿蒙ArkTS提供了@Builder装饰器,结合if/else语句,可以构建出清晰的分支渲染逻辑。

// 使用 @Builder 定义条件渲染的UI块
@Builder RedLightBuilder() {
  Column() {
    Circle({ width: 80, height: 80 })
      .fill(Color.Red)
    Text('停')
      .fontSize(20)
      .fontColor(Color.Red)
  }
}

@Builder GreenLightBuilder() {
  Column() {
    Circle({ width: 80, height: 80 })
      .fill(Color.Green)
    Text('行')
      .fontSize(20)
      .fontColor(Color.Green)
  }
}

@Builder YellowLightBuilder() {
  Column() {
    Circle({ width: 80, height: 80 })
      .fill(Color.Yellow)
    Text('等')
      .fontSize(20)
      .fontColor(Color.Yellow)
  }
}

// 在build()方法中使用if/else进行条件渲染
build() {
  Column({ space: 20 }) {
    // 根据 count % 3 的结果,渲染不同的信号灯
    if (this.count % 3 == 0) {
      this.RedLightBuilder()
    } else if (this.count % 3 == 1) {
      this.GreenLightBuilder()
    } else {
      this.YellowLightBuilder()
    }

    // 切换信号的按钮
    Button('切换信号')
      .onClick(() => {
        // 点击按钮,改变状态变量,触发UI重新渲染
        this.count++
      })
  }
}

代码解析

  1. @Builder装饰的方法封装了要渲染的UI组件。
  2. build()中,if (this.count % 3 == 0) 判断当前count除以3的余数。
  3. 根据余数(0, 1, 2)的值,决定调用哪个Builder来渲染对应的红、绿、黄灯。
  4. 按钮的onClick事件处理器修改了@State变量count,状态变化自动触发了条件判断的重新执行和UI更新。

五、条件渲染核心语法二:三元表达式

对于简单的“二选一”场景,三元表达式提供了更简洁的写法。

三元表达式语法

条件 ? 表达式1 : 表达式2

语法说明

  • 条件:一个返回布尔值的表达式(如 this.count % 2 == 0)。
  • 表达式1:当条件为 true 时返回的值或组件属性。
  • 表达式2:当条件为 false 时返回的值或组件属性。

三元表达式的用法详解

在鸿蒙ArkTS中,三元表达式不能作为独立语句写在build()中,必须嵌入到组件的属性参数里使用。它最常见的用法有两种:

1. 控制文本内容

将三元表达式作为Text组件的文本参数,根据条件动态显示不同的文字:

Text(this.count % 2 == 0 ? '-- 绿灯行 --' : '-- 红灯停 --')
    .fontSize(20)

count为偶数时显示“绿灯行”,奇数时显示“红灯停”。

2. 控制组件属性

三元表达式也可以用在组件的属性链式调用中,动态设置样式:

Text(this.count % 2 == 0 ? '-- 绿灯行 --' : '-- 红灯停 --')
    .fontSize(20)
    .fontColor(this.count % 2 == 0 ? Color.Green : Color.Red)

这里不仅文本内容随条件变化,字体颜色也同步切换——偶数时绿色,奇数时红色。

错误用法对比

build() {
  Column({ space: 20 }) {
    // ❌ 错误用法:会报 Only UI component syntax can be written here.
    // (this.count % 2 == 0) ?
    //     Text('-- 绿灯行 --').fontSize(20).fontColor(Color.Green)
    //     :
    //     Text('-- 红灯停 --').fontSize(20).fontColor(Color.Red)

    // ✅ 正确用法:将三元表达式作为 Text 组件的文本参数
    Text(this.count % 2 == 0 ? '-- 绿灯行 --' : '-- 红灯停 --')
        .fontSize(20)
        .fontColor(this.count % 2 == 0 ? Color.Green : Color.Red)

    Button('切换信号')
      .onClick(() => {
        this.count++
      })
  }
}

适用场景建议

三元表达式非常适合简单的条件渲染,但如果是像红绿灯这样的“三选一”或更复杂的分支,if/else if/else的结构会更清晰。

六、重要注意事项与常见错误

在使用条件渲染时,请务必牢记以下关键点:

6.1 渲染块内只能包含UI声明语句

错误示例

if (this.count % 3 == 0) {
  this.RedLightBuilder()
  this.count++ // ❌ 错误!不能在渲染块内执行逻辑操作
}

正确做法:所有业务逻辑(如状态修改、计算)都应在事件回调(如onClick)或生命周期函数中执行,UI渲染块只负责描述视图。

6.2 确保状态变化可观测

驱动条件渲染的状态变量必须使用响应式装饰器,如@State, @Prop, @Link, @StorageLink等。使用普通变量修改不会触发UI更新。

6.3 选择合适的分支语法

  • 复杂多分支:使用 if/else if/else,结构清晰。
  • 简单二选一:使用 三元表达式,代码简洁。
  • @Builder或子组件结合:可以更好地复用UI和逻辑。

七、完整示例代码

以下是红绿灯模拟应用的完整代码,你可以直接复制到 Index.ets 页面组件中运行。

// 完整红绿灯示例
@Entry
@Component
struct TrafficLightPage {
  @State count: number = 0

  // 定义三个信号灯Builder
  @Builder RedLight() {
    Column({ space: 10 }) {
      Circle().width(100).height(100).fill(Color.Red)
      Text('停').fontSize(24).fontColor(Color.Red)
    }
  }

  @Builder GreenLight() {
    Column({ space: 10 }) {
      Circle().width(100).height(100).fill(Color.Green)
      Text('行').fontSize(24).fontColor(Color.Green)
    }
  }

  @Builder YellowLight() {
    Column({ space: 10 }) {
      Circle().width(100).height(100).fill(Color.Yellow)
      Text('等').fontSize(24).fontColor(Color.Yellow)
    }
  }

  build() {
    Column({ space: 30 }) {
      // 主条件渲染区域:三选一红绿灯
      if (this.count % 3 == 0) {
        this.RedLight()
      } else if (this.count % 3 == 1) {
        this.GreenLight()
      } else {
        this.YellowLight()
      }

      Divider().strokeWidth(1)

      // 三元表达式示例区域:二选一文本(嵌入到Text组件属性中)
      Text(this.count % 2 == 0 ? '-- 绿灯行 --' : '-- 红灯停 --')
        .fontSize(20)
        .fontColor(this.count % 2 == 0 ? Color.Green : Color.Red)

      Button('切换信号')
        .width(200)
        .height(50)
        .fontSize(18)
        .onClick(() => {
          this.count++
          console.log(`当前信号索引: ${this.count}, 对应灯: ${this.count % 3}`)
        })

      Text(`点击次数: ${this.count}`)
        .fontSize(16)
        .fontColor(Color.Gray)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

运行效果:

在这里插入图片描述

八、总结

通过这个红绿灯示例,我们掌握了鸿蒙条件渲染的两大核心武器:

  1. @Builder + if/else:适用于多分支、结构复杂的UI渲染,逻辑清晰,易于维护。
  2. 三元表达式:适用于简单的二选一场景,代码极度精简。

核心思想状态驱动视图。你只需要管理好状态变量(如count),ArkUI框架会自动根据状态的变化,计算出需要渲染的UI分支,并高效地更新界面。

条件渲染是构建动态、交互式应用的基石。接下来,你可以尝试将其与ForEach循环渲染结合,来构建列表等更复杂的界面。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐