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

这是一个使用鸿蒙技术开发的本地原生记账应用,非常适合大家用来练手。相关源码已上传至 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循环渲染结合,来构建列表等更复杂的界面。

相关推荐
猫3281 小时前
echarts 日常问题解决
前端·javascript·echarts
新中地GIS开发老师1 小时前
地信职业百科④:GIS开发工程师
前端·数据库·gis·webgis·三维gis开发
我是大卫1 小时前
【图】React源码解析-从数据结构、调度器、源码设计模式到状态计算引擎,深挖useReducer原理
前端·react.js·源码
willes2 小时前
列表中的倒计时组件
前端
LVZ2 小时前
用了半年 AI 写代码,最烦的不是代码,是环境
前端·后端·开源
polaris_tl2 小时前
一行 `compress: false`,为什么让 SSE 首包恢复实时返回
前端
Catrice02 小时前
HarmonyOS ArkTS 实战:实现一个校园证件照拍摄与预约应用
华为·harmonyos
海边的云2 小时前
别再让 AI 瞎改代码:一套让大模型「收敛」的前端专家 Skill》
前端
kisshyshy2 小时前
给端侧大模型装上“发动机”:React 合成事件 + 进度条组件全解
前端·react.js·node.js