优雅的@ObservedV2和@Trace装饰器

举报
威哥爱编程 发表于 2024/12/11 14:25:42 2024/12/11
【摘要】 Hello,大家好,我是 V 哥。在HarmonyOS NEXT开发中,@ObservedV2装饰器和@Trace装饰器是用于状态管理的两个装饰器,它们在HarmonyOS应用开发中用于增强对类对象中属性的观测能力。如果你学过观察者模式的原理,你会更容易理解和上手,以下是它们的一些关键特性和使用注意事项: @ObservedV2和@Trace装饰器的关键特性@ObservedV2装饰器:需要...

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装饰,表示这是一个需要被观测的类
@ObservedV2
class Product {
  // 商品名称,被@Trace装饰,表示这个属性的变化需要被观测
  @Trace name: string;

  // 商品价格,被@Trace装饰,表示这个属性的变化需要被观测
  @Trace price: number;

  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }
}

// 组件类,用于展示商品信息
@ComponentV2
struct 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
@ComponentV2
struct Index {
  build() {
    Row() {
      ProductComponent();
    }
  }
}

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

image.png

优势

  • 相比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应用开发中的状态管理更加灵活和强大,尤其是在处理复杂对象和深层次属性变化时,提供了更好的解决方案。关注威哥爱编程,一起鸿蒙起来。鸿蒙你我他,生态靠大家。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。