当前位置: 首页 > news >正文

【HarmonyOS】List组件多层对象嵌套ForEach渲染更新完全指南(@Observed、@ObjectLink、@State、Array刷新原理

一、前言

很多HarmonyOS开发者都会遇见下面这种情况。

例如:

@State list: User[] = []

页面:

List() { ForEach(this.list, (item) => { ListItem() { Text(item.name) } }) }

点击按钮:

this.list[0].name = "Tom"

结果:

UI没有刷新!!

很多人第一反应:

我不是修改数据了吗?

实际上:

ArkUI并不是监听Java Bean,也不是Vue那种Proxy。

它有自己的响应式系统。

理解它以后,所有刷新问题都会迎刃而解。


二、List为什么不刷新?

例如:

class User { id:number name:string }

页面:

@State users:User[] = [ new User(1,"Jack"), new User(2,"Rose") ]

List

List(){ ForEach(this.users,(item)=>{ ListItem(){ Text(item.name) } }) }

点击:

this.users[0].name="Lucy"

发现:

页面没变化

为什么?

因为:

State │ │ users(Array) │ ├────User │ │ │ name │ ├────User

ArkUI只知道:

users

并不知道:

users[0].name

发生变化。


三、ArkUI真正监听的是谁?

实际上监听的是:

变量引用

例如:

@State users=[]

监听的是:

users

不是:

users[0]

更不是:

users[0].name

所以:

users.push()

刷新。

因为:

Array改变

users[0].name="Tom"

没有通知State。


四、ForEach刷新机制

很多人认为:

ForEach

每次都会重新执行。

实际上不是。

真正流程:

State变化 ↓ Array Diff ↓ 计算新增 ↓ 计算删除 ↓ 计算移动 ↓ 更新对应ListItem

所以:

ForEach不是重新创建全部Item

而是:

Diff更新

五、为什么官方要求Key?

例如:

ForEach( list, (item)=>{ }, item=>item.id )

这里:

id

就是Diff依据。

没有Key:

全部刷新

有Key:

精准刷新

这就是Recycler思想。


六、多层对象嵌套

实际项目:

class User{ id:number info:UserInfo }

UserInfo

class UserInfo{ avatar:string nick:string }

页面:

Text(item.info.nick)

点击:

item.info.nick="Tom"

结果:

仍然不刷新

为什么?

因为:

State ↓ User ↓ UserInfo ↓ nick

State根本不知道:

nick

发生变化。


七、三层对象更加明显

例如:

Order ↓ Goods ↓ Sku ↓ Price

修改:

order.goods.sku.price=100

页面:

不会刷新

原因完全一样。


八、正确方案一:整体替换对象

例如:

this.users[0] = { ...this.users[0], name:"Tom" }

然后:

this.users=[...this.users]

这样:

Array引用变化

UI刷新。

优点:

简单

缺点:

大量对象复制

九、正确方案二:@Observed

定义:

@Observed class User{ id:number name:string }

List:

@State users:User[]=[]

Item:

@Component struct Item{ @ObjectLink user:User build(){ Text(this.user.name) } }

修改:

user.name="Lucy"

立即刷新。

原因:

Observed ↓ 属性变化 ↓ ObjectLink收到通知 ↓ 组件刷新

十、多层对象如何写?

例如:

@Observed class Address{ city:string }

再定义:

@Observed class User{ address:Address }

Item:

@ObjectLink user:User

修改:

user.address.city="北京"

即可触发深层更新。


十一、ForEach嵌套ForEach

例如:

List(){ ForEach(orderList,(order)=>{ ListItem(){ Column(){ Text(order.name) ForEach(order.goods,(good)=>{ Text(good.name) }) } } }) }

更新:

good.name="苹果"

如果:

没有Observed

不会刷新。

正确方案:

Goods ↓ Observed ↓ ObjectLink ↓ Item组件

十二、企业项目推荐架构

推荐拆分:

Page ↓ OrderList ↓ OrderItem ↓ GoodsList ↓ GoodsItem

数据:

@State ↓ @ObjectLink ↓ @Observed

形成完整响应链:

State ↓ Observed ↓ ObjectLink ↓ UI

这样即使四层、五层对象嵌套,也只刷新发生变化的组件,而不会整页重建。


十三、常见踩坑总结

问题原因推荐方案
修改对象属性不刷新@State不监听对象成员使用@Observed + @ObjectLink
List 更新整个页面未设置稳定 KeyForEach提供唯一id
嵌套对象不刷新深层对象未观察所有需要响应更新的类使用@Observed
@Prop修改无效单向传递,不支持回写改用@Link@ObjectLink
每次刷新整个 List替换整个数组组件拆分 + 精细化更新

十四、最佳实践

在企业级 HarmonyOS 项目中,建议遵循以下原则:

  • 列表数据必须提供稳定唯一的 Key,避免使用索引作为 Key。
  • 列表项拆分为独立组件,降低刷新粒度。
  • 可变对象统一使用@Observed修饰。
  • 子组件通过@ObjectLink持有对象引用,实现属性级更新。
  • 避免频繁整体替换数组,减少内存分配和 Diff 开销。
  • 复杂业务(如电商、IM、通讯录)采用多层组件结构,让刷新范围限制在最小组件。
http://www.cnnetsun.cn/news/3321798.html

相关文章:

  • 从“等客进店”到“上门成交”:服装门店移动POS离店收银的完整业务流程2026
  • 如何用Tabby的分屏和SSH功能实现高效多任务终端管理:完整指南
  • AI编程与低代码平台有什么区别?2026年企业如何选择AI开发工具
  • 工业具身智能开启从技术验证向场景落地的进阶
  • mac玩超级变色龙的方法 mac怎么玩超级变色龙
  • IbPy终极指南:如何快速连接TWS实现Python程序化交易
  • 如何用LocalAI打破云端AI垄断:完全本地化的开源AI引擎终极指南
  • 为什么 Transformer 模型位置编码选择三角函数?
  • Cortex M7-TRM 翻译系列之Programmers Model(二)
  • 解放双手!MAA助手3步实现《明日方舟》全自动化日常管理
  • DAY1 初步认识github平台
  • 北京积水潭医院贵州医院双院区全栈国产化实战:40+模块批量上线与跨院区数据互通方案
  • python神经网络编程入门(七)——跑通MNIST手写数字识别,验证训练成果与测试准确率。
  • 019-费曼学习法与主动回忆的互补
  • 安全剖析:git-credential-oauth如何保护你的Git认证信息不被泄露
  • 终极PUBG罗技鼠标宏压枪脚本完整指南:快速掌握精准射击
  • 基于大模型的数据库自动化测试:从SQL生成到回归验证的智能流水线设计
  • 企业级应用:git-credential-oauth在团队环境中的部署与策略建议
  • React Glow最佳实践:避免常见陷阱的10个技巧
  • 龍魂·鸿蒙网络请求工程化:Axios封装深度解析与实战技术文档
  • Transformers-Tutorials:100+个实战教程,手把手教你玩转AI模型
  • DeltaForce-OBS-Locker深度解析:计算机视觉技术在游戏辅助中的创新应用与架构设计
  • Kohya_SS完整指南:从零开始掌握AI模型训练的终极教程
  • Bilibili-Old终极指南:三步恢复B站经典界面,找回你的青春记忆
  • ret2csu全网超详细讲解!!!
  • CMake 3.24 跨平台构建实战:Windows/Linux/macOS 3系统配置与5个常见问题解决
  • 《凌微经 · 理悖相涵》第十一章 人生修养——本觉心明之洞察
  • 浏览器自动化终极指南:如何用AI智能助手轻松掌控网页操作
  • 终极Android Studio中文语言包:3分钟实现完整界面汉化指南
  • AI 应用灰度发布 ROI 计算:小流量验证的成本节省公式