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

3 回复

装饰器说明@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


ArkTS的@Observed装饰器对嵌套对象的响应式更新采用字段级依赖收集。当使用@Observed装饰嵌套对象的类时,系统会为每个被装饰类的属性建立独立的观察和依赖追踪。这意味着只有实际被访问和使用的特定属性变化才会触发UI更新,而不是整个对象的变化。这提高了更新效率,避免了不必要的渲染。

在HarmonyOS Next的ArkUI中,@Observed装饰器配合@ObjectLink@Prop等装饰器使用时,其依赖收集的粒度是对象级的,而非字段级。

针对你的具体场景分析:

  1. user.profile.avatar被修改时,仅依赖user.profile.name的组件也会被触发重渲染
  2. 这是因为@Observed装饰的类(如Profile)被框架视为一个可观察的整体。框架会追踪到Profile对象本身发生了变化(即对象的引用或内部状态发生了变更),但不会深入到对象内部去追踪是哪个具体字段(nameavatar)被修改了。

依赖图构建机制:

  • 观察对象@Observed装饰器标记的类(如UserProfile)的实例会被框架代理,使其成为可观察对象。
  • 建立连接:当UI组件通过@ObjectLink@Prop装饰的变量(例如@ObjectLink profile: Profile)使用这些对象时,框架会在该组件和这个具体的对象实例之间建立一个监听关系。
  • 触发更新:当这个被观察的对象实例的任何属性发生变化时(无论是name还是avatar),框架都会判定该对象已更新,并通知所有直接监听这个特定对象实例的UI组件进行重渲染检查。

结论: 这种对象级的依赖收集是一种在性能和开发体验上的平衡策略。它避免了深度的、细粒度的字段追踪带来的开销,同时确保了数据变更时UI的一致性更新。开发者需要理解,对嵌套@Observed对象任何属性的修改,都会触发依赖于该对象整体的UI更新。

回到顶部