写点什么

优雅的 @ObservedV2 和 @Trace 装饰器

作者:威哥爱编程
  • 2024-12-11
    北京
  • 本文字数:1985 字

    阅读完需:约 7 分钟

Hello,大家好,我是 V 哥。在 HarmonyOS NEXT 开发中,@ObservedV2 装饰器和 @Trace 装饰器是用于状态管理的两个装饰器,它们在 HarmonyOS 应用开发中用于增强对类对象中属性的观测能力。如果你学过观察者模式的原理,你会更容易理解和上手,以下是它们的一些关键特性和使用注意事项:

@ObservedV2 和 @Trace 装饰器的关键特性

@ObservedV2 装饰器


  • 需要放在类的定义前,使用new创建类对象。

  • 单独使用 @ObservedV2 装饰器没有任何作用,需要与 @Trace 装饰器配合使用。

  • 在嵌套类中,嵌套类中的属性被 @Trace 装饰且嵌套类被 @ObservedV2 装饰时,才具有触发 UI 刷新的能力。

  • 在继承类中,父类或子类中的属性被 @Trace 装饰且该属性所在类被 @ObservedV2 装饰时,才具有触发 UI 刷新的能力。

  • 未被 @Trace 装饰的属性用在 UI 中无法感知到变化,也无法触发 UI 刷新。

  • @ObservedV2 的类实例目前不支持使用JSON.stringify进行序列化。


@Trace 装饰器


  • 用于装饰被 @ObservedV2 装饰的 class 中的属性,使得属性具有深度观测的能力。

  • 可以装饰的变量类型包括numberstringbooleanclassArrayDateMapSet等类型。

  • 被 @Trace 装饰器装饰的属性变化时,仅会通知属性关联的组件进行刷新。

使用注意事项

  • 要监听的属性要添加 @Trace 装饰器。

  • 被监听的属性所在的类要添加 @ObservedV2。

  • 继承类中,继承其中的被监听的属性时,可以等价视为是给出自己的类添加了 @Trace 装饰器监听。

  • @ObservedV2 的类实例目前不支持使用JSON.stringify进行序列化,至于原因是啥,V 哥在文末解释。

  • 继承自 @ObservedV2 的类无法和 @State 等 V1 的装饰器混用,运行时报错。

业务场景代码案例

假设我们有一个电商应用,需要展示商品的名称和价格,并且当价格更新时,界面能够响应变化。


// 商品类,被@ObservedV2装饰,表示这是一个需要被观测的类@ObservedV2class Product {  // 商品名称,被@Trace装饰,表示这个属性的变化需要被观测  @Trace name: string;
// 商品价格,被@Trace装饰,表示这个属性的变化需要被观测 @Trace price: number;
constructor(name: string, price: number) { this.name = name; this.price = price; }}
// 组件类,用于展示商品信息@ComponentV2struct ProductComponent { // 商品实例,使用@Local装饰,表示这是一个局部状态 @Local product: Product = new Product("V哥小炒肉", 100);
build() { Column() { Text(`Name: ${this.product.name}`) .fontSize(30) .fontWeight(FontWeight.Bold); Text(`Price: ¥${this.product.price}`) .fontSize(30) .fontWeight(FontWeight.Bold); Button("更新价格") .onClick(() => { // 更新商品价格,由于price被@Trace装饰,UI将响应这一变化 this.product.price += 10; }); } .width('100%') .height('100%'); }}
// 入口函数,启动应用@Entry@ComponentV2struct Index { build() { Row() { ProductComponent(); } }}
复制代码


在这个例子中,Product类被@ObservedV2装饰,表示这是一个需要被观测的类。nameprice属性被@Trace装饰,表示这些属性的变化需要被观测。在ProductComponent组件中,我们创建了一个Product实例,并在 UI 中展示它的nameprice。当用户点击按钮时,price属性的值增加,由于它被@Trace装饰,UI 将自动响应这一变化并刷新显示新的价格。



优势


  • 相比 V1 版本,V2 版本提供了更强大的状态管理能力,包括深度观测和深度监听,以及更灵活的装饰器使用。

  • V2 版本增强了观测性能和装饰器的易用性,更有利于组件化开发。


所以建议在开发中使用 V2 版本。

为什么 @ObservedV2 不支持 JSON.stringify?

@ObservedV2 不支持 JSON.stringify 的原因主要有两个方面:


  1. 复杂数据结构和监听器:HarmonyOS 的@ObservedV2类实例设计用于响应式编程,通常用于 UI 框架中的数据绑定。其内部可能包含复杂的数据结构和监听器,这些都不适合直接通过JSON.stringify进行序列化。JSON.stringify主要用于处理简单数据结构,如对象、数组、字符串等,而复杂对象(如包含函数、循环引用或特定类实例)可能无法正确序列化。

  2. 序列化后会有__ob_前缀的问题:被@ObservedV2标记的类及字段,使用JSON.stringify之后字段名称都加上了“__ob_”开头的字段,导致无法反序列化回来。这是因为@ObservedV2装饰器在类实例上添加了一些内部属性和方法来实现响应式功能,这些属性和方法在序列化时会产生问题。


针对@ObservedV2对象,建议通过手动提取需要序列化的数据字段,或者自定义序列化逻辑来转换数据。如果问题依旧没法解决,可能需要考虑其他的数据传递或存储方案。

最后

这些装饰器的引入,使得 HarmonyOS 应用开发中的状态管理更加灵活和强大,尤其是在处理复杂对象和深层次属性变化时,提供了更好的解决方案。关注威哥爱编程,一起鸿蒙起来。鸿蒙你我他,生态靠大家。

发布于: 刚刚阅读数: 4
用户头像

华为 HDE、CSDN 博客专家、Java畅销书作者 2018-05-30 加入

全栈领域优质创作者(Java/HarmonyOS/AI),公众号:威哥爱编程

评论

发布
暂无评论
优雅的@ObservedV2和@Trace装饰器_HarmonyOS_威哥爱编程_InfoQ写作社区