鸿蒙应用开发教程:以红绿灯切换为例,掌握条件渲染的核心用法

这是一个使用鸿蒙技术开发的本地原生记账应用,非常适合大家用来练手。相关源码已上传至 Github,点击此处查看项目。欢迎大家交流、指正,也欢迎提交 PR。

一、引言

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

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

二、项目目标与效果预览

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

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

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

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

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

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

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

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

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

typescript 复制代码
// 使用 @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组件的文本参数,根据条件动态显示不同的文字:

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

当count为偶数时显示"绿灯行",奇数时显示"红灯停"。

2. 控制组件属性

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

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

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

错误用法对比

typescript 复制代码
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声明语句

错误示例:

typescript 复制代码
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 页面组件中运行。

typescript 复制代码
// 完整红绿灯示例
@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循环渲染结合,来构建列表等更复杂的界面。

相关推荐
派小心.4 小时前
DAU和MAU怎么计算?先确定活跃事件、用户键和统计窗口
大数据·服务器·前端·人工智能·数据分析
代码猎人5 小时前
前端怎么配合后端完成bug修复
前端
定栓5 小时前
Webpack迁到Vite第七节(四):全家桶移除 — 保留项、脚本与数据收尾
前端·webpack·node.js
代码猎人5 小时前
前端怎么保障项目稳定上线与运行
前端
数据掘金5 小时前
小程序埋点方案的埋点文档怎么自动生成?
前端
deli0075 小时前
cron 表达式为什么总跑错?10 个场景实测,下次执行时间一眼看懂
前端
代码猎人5 小时前
前端怎么优化页面性能
前端
代码猎人5 小时前
前端怎么配合后端完成数据对接
前端
lexiangqicheng5 小时前
Docker的沙箱机制是怎样的?
前端·javascript
燕落南枝5 小时前
HTML 表格标签与 AI 合并单元格实战指南
前端·人工智能·html