第6篇:条件渲染——根据条件显示内容 鸿蒙中文编程
本文介绍了条件渲染在编程中的应用,重点讲解了if-else条件语句的使用方法。文章从生活中的条件判断引入,展示了程序中常见的条件渲染场景,如登录状态切换、加载状态显示和权限控制等。详细讲解了if-else基础语法、多种条件判断方式(包括if-else if-else和嵌套if)、条件运算符(三元运算符和逻辑运算符)等核心概念。最后通过一个完整的登录状态切换示例代码,演示了如何在实际项目中应用条件渲
·
第6篇:条件渲染——根据条件显示内容
本课目标:掌握if-else条件渲染,能根据状态显示不同内容
**作者:**中文编程倡导者—— 李金雨
预计课时:2课时(90分钟)
难度等级:⭐⭐⭐(进阶)
一、开篇引入
1.1 生活中的"条件"
生活中处处都有"如果…就…":
- 如果下雨,就带伞
- 如果到18岁,就可以考驾照
- 如果成绩>=60,就及格
- 如果登录了,就显示用户名
1.2 程序中的条件
应用界面也需要根据条件显示不同内容:
- 用户登录了 → 显示头像和用户名
- 用户没登录 → 显示"请登录"按钮
- 数据加载中 → 显示转圈圈
- 数据加载完 → 显示内容
- 列表为空 → 显示"暂无数据"
1.3 本课目标
今天我们要学习:
if-else条件渲染- 多种条件判断
- 条件渲染的常见场景
- 实战:登录状态切换、权限控制、加载状态
1.4 预期成果
完成本课后,你能做出这样的应用:
登录状态切换: 加载状态: 权限控制:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ │ │ │ │
│ 未登录时: │ │ ⏳ │ │ 🔒 VIP专区 │
│ │ │ 加载中... │ │ │
│ [登录按钮] │ │ │ │ 普通用户: │
│ │ │ │ │ "请先升级 │
│ 已登录时: │ │ 加载完成: │ │ VIP" │
│ │ │ │ │ │
│ 👤 张三 │ │ [内容显示] │ │ VIP用户: │
│ 退出登录 │ │ │ │ [专属内容] │
│ │ │ │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
二、概念讲解
2.1 if-else基础
基本语法
if (条件) {
// 条件为true时显示的内容
} else {
// 条件为false时显示的内容
}
简单例子
@State 是否登录: boolean = false
build() {
Column() {
if (this.是否登录) {
Text("欢迎回来!")
} else {
Text("请先登录")
}
}
}
2.2 多种条件判断
if-else if-else
多个条件依次判断:
@State 成绩: number = 85
build() {
Column() {
if (this.成绩 >= 90) {
Text("优秀!")
.fontColor("#4CAF50")
} else if (this.成绩 >= 80) {
Text("良好")
.fontColor("#2196F3")
} else if (this.成绩 >= 60) {
Text("及格")
.fontColor("#FF9800")
} else {
Text("不及格")
.fontColor("#F44336")
}
}
}
嵌套if
条件里面还有条件:
if (this.是否登录) {
if (this.是否是VIP) {
Text("欢迎VIP用户!")
} else {
Text("欢迎普通用户")
}
} else {
Text("请先登录")
}
2.3 条件运算符
三元运算符(简单条件)
// 语法:条件 ? 真时的值 : 假时的值
Text(this.是否登录 ? "已登录" : "未登录")
// 等同于:
if (this.是否登录) {
Text("已登录")
} else {
Text("未登录")
}
逻辑运算符
// &&(并且)- 两个条件都满足
if (this.是否登录 && this.是否是VIP) {
Text("VIP会员")
}
// ||(或者)- 满足其中一个
if (this.是管理员 || this.是版主) {
Text("有管理权限")
}
// !(非)- 取反
if (!this.是否登录) {
Text("未登录")
}
2.4 常见条件场景
场景1:登录状态
if (this.是否登录) {
// 显示用户信息
Column() {
Image($r("app.media.avatar"))
Text(this.用户名)
Button("退出登录")
}
} else {
// 显示登录按钮
Column() {
Text("请先登录")
Button("立即登录")
}
}
场景2:加载状态
if (this.是否加载中) {
// 显示加载动画
Column() {
LoadingProgress()
.width(50)
.height(50)
Text("加载中...")
}
} else if (this.是否有错误) {
// 显示错误信息
Text("加载失败,请重试")
} else {
// 显示内容
List() {
ForEach(this.数据列表, (项目) => { /* ... */ })
}
}
场景3:空数据提示
if (this.列表.length == 0) {
// 显示空状态
Column() {
Text("📭")
.fontSize(60)
Text("暂无数据")
.fontColor("#999999")
}
} else {
// 显示列表
ForEach(this.列表, (项目) => { /* ... */ })
}
三、动手实践
3.1 基础练习:登录状态切换
做一个根据登录状态显示不同内容的页面:
// 完整可运行代码,复制到 Index.ets 即可运行
@Entry
@Component
struct Index {
@State 是否登录: boolean = false
@State 用户名: string = "张三"
@State 头像: string = "👤"
build() {
Column() {
// 顶部导航栏
Row() {
Text("用户中心")
.fontSize(20)
.fontWeight(FontWeight.Bold)
if (this.是否登录) {
Text("设置")
.fontSize(14)
.fontColor("#2196F3")
}
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding(20)
.backgroundColor('#FFFFFF')
// 主要内容区域
Column({ space: 20 }) {
if (this.是否登录) {
// 已登录状态
this.已登录界面()
} else {
// 未登录状态
this.未登录界面()
}
}
.width('100%')
.layoutWeight(1)
.padding(20)
// 底部切换按钮(仅用于演示)
Button(this.是否登录 ? "退出登录(演示)" : "模拟登录(演示)")
.width('90%')
.backgroundColor(this.是否登录 ? '#F44336' : '#4CAF50')
.onClick(() => {
this.是否登录 = !this.是否登录
})
.margin({ bottom: 20 })
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
// 已登录界面
@Builder
已登录界面() {
Column({ space: 20 }) {
// 用户信息卡片
Column({ space: 15 }) {
Text(this.头像)
.fontSize(80)
.backgroundColor('#E3F2FD')
.borderRadius(50)
.width(100)
.height(100)
.textAlign(TextAlign.Center)
Text(this.用户名)
.fontSize(24)
.fontWeight(FontWeight.Bold)
Text("普通会员")
.fontSize(14)
.fontColor("#999999")
.padding({ left: 10, right: 10, top: 3, bottom: 3 })
.backgroundColor('#F5F5F5')
.borderRadius(10)
}
.width('100%')
.padding(30)
.backgroundColor('#FFFFFF')
.borderRadius(12)
// 功能菜单
Column({ space: 1 }) {
this.菜单项("📋", "我的订单", "3个未完成")
this.菜单项("❤️", "我的收藏", "12个商品")
this.菜单项("🎫", "优惠券", "2张即将过期")
this.菜单项("⚙️", "设置", "")
this.菜单项("❓", "帮助与反馈", "")
}
.width('100%')
.backgroundColor('#FFFFFF')
.borderRadius(12)
.clip(true)
// 退出登录按钮
Button("退出登录", { type: ButtonType.Capsule })
.width('100%')
.height(50)
.backgroundColor('#FFFFFF')
.fontColor('#F44336')
.border({ width: 1, color: '#F44336' })
.onClick(() => {
this.是否登录 = false
})
}
}
// 未登录界面
@Builder
未登录界面() {
Column({ space: 30 }) {
// 提示图标
Column({ space: 15 }) {
Text("🔒")
.fontSize(100)
Text("您还未登录")
.fontSize(24)
.fontWeight(FontWeight.Bold)
Text("登录后可享受更多功能")
.fontSize(14)
.fontColor("#999999")
}
.margin({ top: 50 })
// 登录按钮
Column({ space: 15 }) {
Button("立即登录", { type: ButtonType.Capsule })
.width('100%')
.height(50)
.backgroundColor('#2196F3')
.onClick(() => {
this.是否登录 = true
})
Button("注册账号", { type: ButtonType.Capsule })
.width('100%')
.height(50)
.backgroundColor('#FFFFFF')
.fontColor('#2196F3')
.border({ width: 1, color: '#2196F3' })
Text("游客模式浏览")
.fontSize(14)
.fontColor("#999999")
.margin({ top: 10 })
}
.width('100%')
.padding({ left: 30, right: 30 })
}
}
// 菜单项组件
@Builder
菜单项(图标: string, 标题: string, 提示: string) {
Row() {
Row({ space: 10 }) {
Text(图标)
.fontSize(20)
Text(标题)
.fontSize(16)
}
Row({ space: 5 }) {
if (提示 != "") {
Text(提示)
.fontSize(12)
.fontColor("#F44336")
}
Text(">")
.fontSize(16)
.fontColor("#CCCCCC")
}
}
.width('100%')
.height(55)
.padding({ left: 15, right: 15 })
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('#FFFFFF')
}
}
3.2 进阶练习:加载状态管理
做一个带多种状态(加载中、成功、失败、空数据)的页面:
// 完整可运行代码,复制到 Index.ets 即可运行
@Entry
@Component
struct Index {
@State 加载状态: string = "加载中" // 加载中、成功、失败、空数据
@State 数据列表: string[] = []
@State 错误信息: string = ""
build() {
Column() {
// 标题栏
Row() {
Text("数据列表")
.fontSize(20)
.fontWeight(FontWeight.Bold)
Row({ space: 10 }) {
Text("模拟:")
.fontSize(12)
.fontColor("#999999")
// 状态切换按钮(仅演示用)
Text("加载")
.fontSize(12)
.padding(5)
.backgroundColor(this.加载状态 == "加载中" ? '#2196F3' : '#F5F5F5')
.fontColor(this.加载状态 == "加载中" ? '#FFFFFF' : '#333333')
.onClick(() => this.模拟加载中())
Text("成功")
.fontSize(12)
.padding(5)
.backgroundColor(this.加载状态 == "成功" ? '#4CAF50' : '#F5F5F5')
.fontColor(this.加载状态 == "成功" ? '#FFFFFF' : '#333333')
.onClick(() => this.模拟成功())
Text("失败")
.fontSize(12)
.padding(5)
.backgroundColor(this.加载状态 == "失败" ? '#F44336' : '#F5F5F5')
.fontColor(this.加载状态 == "失败" ? '#FFFFFF' : '#333333')
.onClick(() => this.模拟失败())
Text("空数据")
.fontSize(12)
.padding(5)
.backgroundColor(this.加载状态 == "空数据" ? '#FF9800' : '#F5F5F5')
.fontColor(this.加载状态 == "空数据" ? '#FFFFFF' : '#333333')
.onClick(() => this.模拟空数据())
}
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding(15)
.backgroundColor('#FFFFFF')
// 内容区域
Column() {
if (this.加载状态 == "加载中") {
this.加载中界面()
} else if (this.加载状态 == "失败") {
this.失败界面()
} else if (this.加载状态 == "空数据") {
this.空数据界面()
} else {
this.成功界面()
}
}
.width('100%')
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
// 加载中界面
@Builder
加载中界面() {
Column({ space: 15 }) {
LoadingProgress()
.width(60)
.height(60)
.color('#2196F3')
Text("正在加载数据...")
.fontSize(16)
.fontColor("#666666")
}
.justifyContent(FlexAlign.Center)
}
// 失败界面
@Builder
失败界面() {
Column({ space: 20 }) {
Text("❌")
.fontSize(60)
Text("加载失败")
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor("#F44336")
Text(this.错误信息 || "网络连接失败,请检查网络设置")
.fontSize(14)
.fontColor("#999999")
.textAlign(TextAlign.Center)
Button("重新加载", { type: ButtonType.Capsule })
.width(150)
.height(40)
.backgroundColor('#2196F3')
.onClick(() => {
this.模拟加载中()
setTimeout(() => this.模拟成功(), 1500)
})
}
.justifyContent(FlexAlign.Center)
}
// 空数据界面
@Builder
空数据界面() {
Column({ space: 15 }) {
Text("📭")
.fontSize(80)
Text("暂无数据")
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor("#666666")
Text("快去添加第一条数据吧")
.fontSize(14)
.fontColor("#999999")
Button("添加数据", { type: ButtonType.Capsule })
.width(150)
.height(40)
.backgroundColor('#4CAF50')
.margin({ top: 10 })
.onClick(() => {
this.模拟成功()
})
}
.justifyContent(FlexAlign.Center)
}
// 成功界面
@Builder
成功界面() {
List({ space: 10 }) {
ForEach(this.数据列表, (项目: string, 索引: number) => {
ListItem() {
Row() {
Text(`${索引 + 1}. ${项目}`)
.fontSize(16)
}
.width('100%')
.height(60)
.padding(15)
.backgroundColor('#FFFFFF')
.borderRadius(8)
}
})
}
.padding(15)
// 刷新按钮
Button("刷新数据")
.width('90%')
.height(45)
.backgroundColor('#2196F3')
.margin({ bottom: 20 })
.onClick(() => {
this.模拟加载中()
setTimeout(() => {
if (Math.random() > 0.3) {
this.模拟成功()
} else {
this.模拟失败()
}
}, 1500)
})
}
// 模拟各种状态
模拟加载中() {
this.加载状态 = "加载中"
}
模拟成功() {
this.数据列表 = ["数据项1", "数据项2", "数据项3", "数据项4", "数据项5"]
this.加载状态 = "成功"
}
模拟失败() {
this.错误信息 = "服务器连接超时"
this.加载状态 = "失败"
}
模拟空数据() {
this.数据列表 = []
this.加载状态 = "空数据"
}
}
3.3 进阶练习:权限控制
做一个根据用户权限显示不同内容的页面:
// 完整可运行代码,复制到 Index.ets 即可运行
@Entry
@Component
struct Index {
@State 用户角色: string = "游客" // 游客、普通用户、VIP、管理员
build() {
Column() {
// 标题
Text("内容权限演示")
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin(20)
// 角色切换(演示用)
Scroll() {
Row({ space: 10 }) {
ForEach(["游客", "普通用户", "VIP", "管理员"], (角色: string) => {
Text(角色)
.fontSize(14)
.padding({ left: 15, right: 15, top: 8, bottom: 8 })
.backgroundColor(this.用户角色 == 角色 ? '#2196F3' : '#F5F5F5')
.fontColor(this.用户角色 == 角色 ? '#FFFFFF' : '#333333')
.borderRadius(20)
.onClick(() => {
this.用户角色 = 角色
})
})
}
.padding(15)
}
.scrollBar(BarState.Off)
.scrollable(ScrollDirection.Horizontal)
// 内容区域
Column({ space: 15 }) {
// 公开内容 - 所有人可见
this.内容卡片("📢 公告", "欢迎访问我们的应用!", "公开", "#4CAF50")
// 登录可见内容
if (this.用户角色 != "游客") {
this.内容卡片("📰 新闻", "今日最新资讯更新...", "登录用户", "#2196F3")
}
// VIP专属内容
if (this.用户角色 == "VIP" || this.用户角色 == "管理员") {
this.内容卡片("👑 VIP专区", "专属优惠和特权内容...", "VIP专属", "#FF9800")
}
// 管理员专属内容
if (this.用户角色 == "管理员") {
this.内容卡片("⚙️ 管理后台", "系统管理和数据统计...", "管理员", "#F44336")
}
// 提示信息
this.权限提示()
}
.width('100%')
.layoutWeight(1)
.padding(15)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
// 内容卡片
@Builder
内容卡片(标题: string, 内容: string, 标签: string, 标签颜色: string) {
Column({ space: 10 }) {
Row() {
Text(标题)
.fontSize(18)
.fontWeight(FontWeight.Bold)
Text(标签)
.fontSize(11)
.fontColor('#FFFFFF')
.padding({ left: 8, right: 8, top: 2, bottom: 2 })
.backgroundColor(标签颜色)
.borderRadius(10)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
Text(内容)
.fontSize(14)
.fontColor("#666666")
}
.width('100%')
.padding(15)
.backgroundColor('#FFFFFF')
.borderRadius(12)
}
// 权限提示
@Builder
权限提示() {
Column({ space: 5 }) {
if (this.用户角色 == "游客") {
Text("💡 提示:登录后可查看更多内容")
.fontSize(12)
.fontColor("#999999")
} else if (this.用户角色 == "普通用户") {
Text("💡 提示:升级VIP解锁更多特权")
.fontSize(12)
.fontColor("#FF9800")
} else if (this.用户角色 == "VIP") {
Text("✨ 您已享受VIP全部特权")
.fontSize(12)
.fontColor("#4CAF50")
} else {
Text("🔧 管理员模式已开启")
.fontSize(12)
.fontColor("#F44336")
}
}
.margin({ top: 10 })
}
}
四、知识总结
4.1 核心概念回顾
- if-else:根据条件显示不同内容
- 条件运算符:简化简单条件的写法
- 逻辑运算符:组合多个条件
- 常见场景:登录状态、加载状态、权限控制
4.2 条件渲染速查
// 基本if-else
if (条件) {
// 真时显示
} else {
// 假时显示
}
// 多条件判断
if (条件1) {
// ...
} else if (条件2) {
// ...
} else {
// ...
}
// 三元运算符
Text(条件 ? "真" : "假")
// 逻辑运算符
if (条件1 && 条件2) { } // 并且
if (条件1 || 条件2) { } // 或者
if (!条件) { } // 取反
4.3 常见场景模板
// 登录状态
if (this.是否登录) {
// 显示用户信息
} else {
// 显示登录按钮
}
// 加载状态
if (this.加载中) {
// 显示加载动画
} else if (this.有错误) {
// 显示错误
} else {
// 显示内容
}
// 空数据
if (this.列表.length == 0) {
// 显示空状态
} else {
// 显示列表
}
4.4 常见错误提醒
| 错误现象 | 原因 | 解决方法 |
|---|---|---|
| 条件不生效 | 条件写错 | 检查条件表达式 |
| 两边都显示 | if-else结构错误 | 检查花括号配对 |
| 界面闪烁 | 条件频繁变化 | 优化状态更新逻辑 |
| 嵌套太深 | 条件太多 | 考虑拆分组件 |
五、课后作业
5.1 巩固练习(必做)
练习1:成绩等级显示
输入成绩,根据分数显示不同等级和颜色:
- 90-100:优秀(绿色)
- 80-89:良好(蓝色)
- 60-79:及格(橙色)
- <60:不及格(红色)
练习2:夜间模式切换
做一个可以切换白天/夜间模式的应用:
- 白天:白色背景,黑色文字
- 夜间:深色背景,白色文字
练习3:表单验证
做一个注册表单:
- 用户名不能为空
- 密码至少6位
- 两次密码要一致
- 根据验证结果显示不同提示
5.2 创意编程(选做)
创意1:游戏角色选择
- 选择不同角色显示不同属性
- 战士:高攻击
- 法师:高魔法
- 牧师:高治疗
创意2:天气预报
- 根据天气显示不同图标和背景
- 晴天、雨天、雪天、多云
创意3:智能助手
- 输入问题,根据关键词显示不同回答
- “你好"→"你好!”
- "时间"→显示当前时间
- "帮助"→显示帮助信息
5.3 下篇预习
下一篇,我们将学习功能定义,封装可复用的代码。预习问题:
- 怎么把重复的代码提取出来?
- 怎么给代码起名字?
- 怎么使用封装好的代码?
恭喜你完成了第6篇的学习! 🎉
现在你已经掌握了条件渲染,可以做出根据状态动态变化的应用了。记住:if-else让界面更智能,条件渲染让应用更灵活!
下节课,我们将学习如何封装可复用的代码!
更多推荐


所有评论(0)