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中的属性,使得属性具有深度观测的能力。
- 可以装饰的变量类型包括
number
、string
、boolean
、class
、Array
、Date
、Map
、Set
等类型。 - 被@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
装饰,表示这是一个需要被观测的类。name
和price
属性被@Trace
装饰,表示这些属性的变化需要被观测。在ProductComponent
组件中,我们创建了一个Product
实例,并在UI中展示它的name
和price
。当用户点击按钮时,price
属性的值增加,由于它被@Trace
装饰,UI将自动响应这一变化并刷新显示新的价格。
优势:
- 相比V1版本,V2版本提供了更强大的状态管理能力,包括深度观测和深度监听,以及更灵活的装饰器使用。
- V2版本增强了观测性能和装饰器的易用性,更有利于组件化开发。
所以建议在开发中使用 V2版本。
为什么@ObservedV2不支持JSON.stringify?
@ObservedV2不支持JSON.stringify的原因主要有两个方面:
- 复杂数据结构和监听器:HarmonyOS的
@ObservedV2
类实例设计用于响应式编程,通常用于UI框架中的数据绑定。其内部可能包含复杂的数据结构和监听器,这些都不适合直接通过JSON.stringify
进行序列化。JSON.stringify
主要用于处理简单数据结构,如对象、数组、字符串等,而复杂对象(如包含函数、循环引用或特定类实例)可能无法正确序列化。 - 序列化后会有
__ob_
前缀的问题:被@ObservedV2
标记的类及字段,使用JSON.stringify
之后字段名称都加上了“__ob_
”开头的字段,导致无法反序列化回来。这是因为@ObservedV2
装饰器在类实例上添加了一些内部属性和方法来实现响应式功能,这些属性和方法在序列化时会产生问题。
针对@ObservedV2
对象,建议通过手动提取需要序列化的数据字段,或者自定义序列化逻辑来转换数据。如果问题依旧没法解决,可能需要考虑其他的数据传递或存储方案。
最后
这些装饰器的引入,使得HarmonyOS应用开发中的状态管理更加灵活和强大,尤其是在处理复杂对象和深层次属性变化时,提供了更好的解决方案。关注威哥爱编程,一起鸿蒙起来。鸿蒙你我他,生态靠大家。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。