【鸿蒙心迹】HarmonyOS笔记14:ForEach简单列表
🔥 个人主页: 杨利杰YJlio
❄️ 个人专栏: 《Windows 疑难杂症与工单复盘案例库》 《Sysinternals实战教程》
《WINDOWS教程》 《Windows PowerShell 实战》 《IOS插件分析测试》
🌟 让复杂的事情更简单,让重复的工作自动化


文章目录
前言:先把数组与界面对应起来
大家好,我是杨利杰 YJlio。
第14篇我用 ForEach 展示两条工单标题:网络无法连接、打印机驱动安装。先阅读数据怎样生成重复子组件,再区分显示文字与键值标识。
原稿提供的是学习片段,没有设备运行记录。本篇保留原稿,在正文补充键值限制和同名数据示例;所有配图都是结构或文案示意。
显示文字说明内容,键值标识帮助区分数据项,两者不能无条件等同。
| 环境项 | 实际记录 |
|---|---|
| DevEco Studio、SDK/API | 待填写 |
| 模板与入口组件 | 待填写 |
| 设备、系统与窗口 | 待填写 |
| 构建与运行结果 | 待填写 |
一、ForEach 描述重复子组件
我先把数据数组、重复生成与布局容器拆开看。

ForEach 在 ArkUI 声明式 UI 中根据数据生成子组件,不是普通数组 forEach 的替代名称。JavaScript 数组遍历与 UI 渲染控制属于不同用途。
Column 负责排列,Text 显示每项文字;ForEach 负责重复生成。本例没有网络请求,也没有读取工单数据库。
华为列表布局说明展示了 ForEach 与列表容器的结合。本文先用 Column 阅读少量内容,不将它称为已实现可滚动的大数据列表。
二、先保留两个明确的字符串
我先确认数据内容,再判断页面是否与数据一致。

| 位置 | 演示内容 |
|---|---|
| 第一项 | 网络无法连接 |
| 第二项 | 打印机驱动安装 |
这些是练习文案,不是真实工单记录,没有状态、创建时间或处理结果。配图不添加原数据没有的字段。
两个字符串不同,因此原稿的字符串键在这份初始数据中不重复。但如果以后出现同名内容,不能继续依赖这个条件。
三、阅读原稿的最小列表片段
我保留原稿的数据与 Text 内容,先把重复关系读清楚。

以下片段位于组件声明内部,需接入当前模板的入口和组件声明,不能当作完整文件直接替换。
@State tickets: string[] = ['网络无法连接', '打印机驱动安装']
build() {
Column() {
ForEach(this.tickets, (ticket: string) => {
Text(ticket).padding(12)
}, (ticket: string) => ticket)
}
}
padding(12) 是演示配置,不是设备实测尺寸。两条文案按数组顺序生成;配图只是文本结构,没有表达实际字体、窗口或像素比例。
本例没有 List、ListItem 或滚动容器,也没有点击事件。需要滚动和更大数据量时,再按场景选择合适容器与渲染方式,不提前声明性能结论。
四、键值生成函数要有明确依据
原稿的最后一个回调返回 ticket,也就是把字符串内容作为标识。

这适合阅读无重复、内容不变的静态小例子。业务中,同名标题、文字编辑和排序都可能让这条规则不再合适。
键值应在同一次渲染集合中区分项目;是否需要因内容修改而重新生成子组件,还要按实际渲染规则与状态更新方式判断。稳定身份是设计依据,不能当成“任何内容改变都自动刷新”的保证。
不要为了让列表看起来刷新,就在键值生成函数里每次制造随机身份。
生成规则、依赖 index 时的行为和子组件更新条件,需要结合当前 ForEach 文档确认,不能从其他渲染机制直接推断。
五、同名数据用独立标识区分
我补一个同名标题例子,展示为什么文字不能总承担身份。

下面是新增学习片段:接口放在组件外,状态字段与 build() 放在对应组件内。这组数据不能与上一节同名字段同时粘贴。
interface TicketItem {
id: string
title: string
}
@State ticketItems: TicketItem[] = [
{ id: 'ticket-001', title: '网络无法连接' },
{ id: 'ticket-002', title: '网络无法连接' }
]
build() {
Column() {
ForEach(this.ticketItems, (item: TicketItem) => {
Text(item.title).padding(12)
}, (item: TicketItem) => item.id)
}
}
两个演示标识不同,标题相同。图中显示标识用于解释数据身份;上述 Text 只显示 title,不会把 id 自动显示到页面。
这里没有后端或数据库,ID 是演示值。实际业务应使用能识别同一条记录的来源标识,并核对同一集合内没有重复。
稳定 ID 也不能替代对象字段观察机制。后续若修改对象 title,需要按照当前状态管理版本验证更新行为。
六、当前位置不等于业务身份
索引可以说明当前顺序,但插入、删除或重排后,位置可能改变。

我会先问:数据项移动以后,它还是不是同一条记录?如果是,标识就不应仅因为当前位置改变而任意变成另一条身份。
不能把 index 键写成所有场景都错误,也不能把它写成通用修复。要结合数据是否会变动、子组件是否包含状态以及渲染规则决定。
本篇没有做节点复用、性能或重排测试,因此不写快了多少,也不展示虚构的错位截图。
七、数据变化与界面更新分开排查
看到界面不更新时,我先确认数据与观察路径,而不是先改键值。

- 确认事件或代码是否真的改变数据。
- 检查数据属于哪一种状态管理方式。
- 核对更新形式是否在当前观察范围内。
- 检查键值规则是否区分预期数据项。
- 查看子组件实际读取的是哪个字段。
数据已改变不等于页面一定更新,键值正确也不等于状态观察路径正确。
@State 示例要与当前模板版本一致,不混用不同装饰器。本篇先阅读数据与标识,下一篇再集中讨论页面没有刷新。
八、用小数据记录四种情况
我会在独立练习工程中分别观察初始内容、空数组、重复标题和重排。

| 场景 | 观察重点 | 实际结果 |
|---|---|---|
| 初始两项 | 两段文字与数据对应 | 待填写 |
| 空数组 | 重复子组件为空;空态需另写 | 待填写 |
| 同名标题不同 ID | 标识不同、显示文字相同 | 待填写 |
| 重排 | 顺序、身份及组件行为 | 待填写 |
空数组不自动生成“暂无数据”提示;有需要就另加条件渲染。重复键的异常表现也应据当前工程日志记录,不在配图中预设结果。
保存入口路径、SDK/API、操作步骤与完整构建日志。生成图不能代替设备画面,未经实际运行的项目仍保留待验证状态。
学习总结
这篇我从两个字符串开始,用 ForEach 阅读重复子组件,再把同名标题与独立 ID 分开。列表不仅要显示正确文案,还要说明数据身份如何确定。
下一篇讨论为什么状态变化后页面没有刷新。发布前补齐实际工程、运行记录与异常证据。
参考资料
声明:本文为列表学习示例,配图为结构与文案示意;语法、键值、状态与运行结果以当前模板、SDK、实际设备及官方文档为准。

更多推荐


所有评论(0)