HarmonyOS鸿蒙Next中ArkTS的@Observed装饰器对嵌套对象的响应式更新,其依赖收集(dependency tracking)粒度是字段级还是对象级?
HarmonyOS鸿蒙Next中ArkTS的@Observed装饰器对嵌套对象的响应式更新,其依赖收集(dependency tracking)粒度是字段级还是对象级?
技术描述:
考虑以下结构:
[@Observed](/user/Observed) class Profile { name: string; avatar: string; }
[@Observed](/user/Observed) class Profile { name: string; avatar: string; }
当 user.profile.avatar = "new.jpg" 时,仅使用 user.profile.name 的组件是否会被触发重渲染?依赖图是如何构建的?
更多关于HarmonyOS鸿蒙Next中ArkTS的@Observed装饰器对嵌套对象的响应式更新,其依赖收集(dependency tracking)粒度是字段级还是对象级?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
装饰器说明,@Observed用于对象数组、数组对象、嵌套对象场景中,观察对象类属性变化,用于修饰类。建立的是与整个对象实例的绑定关系。
如只使用user.profile.name的Text组件会触发重新渲染。
框架行为,@Observed装饰的class的实例会被不透明的代理对象包装,代理了class上的属性的setter和getter方法
子组件中@ObjectLink装饰的从父组件初始化,接受被@Observed装饰的class的实例,@ObjectLink 的包装类会将自己注册给@Observed class。
当@Observed装饰的class属性改变时,会走到代理的setter和getter,然后遍历依赖它的@ObjectLink包装类,通知数据更新。
更多关于HarmonyOS鸿蒙Next中ArkTS的@Observed装饰器对嵌套对象的响应式更新,其依赖收集(dependency tracking)粒度是字段级还是对象级?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next的ArkUI中,@Observed装饰器配合@ObjectLink或@Prop等装饰器使用时,其依赖收集的粒度是对象级的,而非字段级。
针对你的具体场景分析:
- 当
user.profile.avatar被修改时,仅依赖user.profile.name的组件也会被触发重渲染。 - 这是因为
@Observed装饰的类(如Profile)被框架视为一个可观察的整体。框架会追踪到Profile对象本身发生了变化(即对象的引用或内部状态发生了变更),但不会深入到对象内部去追踪是哪个具体字段(name或avatar)被修改了。
依赖图构建机制:
- 观察对象:
@Observed装饰器标记的类(如User和Profile)的实例会被框架代理,使其成为可观察对象。 - 建立连接:当UI组件通过
@ObjectLink或@Prop装饰的变量(例如@ObjectLink profile: Profile)使用这些对象时,框架会在该组件和这个具体的对象实例之间建立一个监听关系。 - 触发更新:当这个被观察的对象实例的任何属性发生变化时(无论是
name还是avatar),框架都会判定该对象已更新,并通知所有直接监听这个特定对象实例的UI组件进行重渲染检查。
结论:
这种对象级的依赖收集是一种在性能和开发体验上的平衡策略。它避免了深度的、细粒度的字段追踪带来的开销,同时确保了数据变更时UI的一致性更新。开发者需要理解,对嵌套@Observed对象任何属性的修改,都会触发依赖于该对象整体的UI更新。

