@State
、@Prop
、@Link
、@Provide
等装饰器仅能观察到第一层的变化,但是在实际应用开发中,应用会根据开发需要,封装自己的数据模型。对于多层嵌套的情况,比如二维数组,或者数组项class,或者class
的属性是class
,他们的第二层的属性变化是无法观察到的。这就引出了@Observed/@ObjectLink
装饰器。
@ObjectLink
和@Observed
类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步:
@Observed
装饰的类,可以被观察到属性的变化;@ObjectLink
装饰器装饰的状态变量用于接收@Observed
装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed
装饰的项,或者是class object
中的属性,这个属性同样也需要被@Observed
装饰。@Observed
是没有任何作用的,需要搭配@ObjectLink
或者@Prop
使用。@Observed
装饰class
会改变class
原始的原型链,@Observed
和其他类装饰器装饰同一个class
可能会带来问题。@ObjectLink
装饰器不能在@Entry
装饰的自定义组件中使用。@Observed类装饰器 | 说明 |
---|---|
装饰器参数 | 无 |
类装饰器 | 装饰class。需要放在class的定义前,使用new创建类对象。 |
@ObjectLink变量装饰器 | 说明 |
---|---|
装饰器参数 | 无 |
同步类型 | 不与父组件中的任何类型同步变量。 |
允许装饰的变量类型 | 必须为被@Observed装饰的class实例,必须指定类型。不支持简单类型,可以使用@Prop。@ObjectLink的属性是可以改变的,但是变量的分配是不允许的,也就是说这个装饰器装饰变量是只读的,不能被改变。 |
被装饰变量的初始值 | 不允许。 |
// 允许@ObjectLink装饰的数据属性赋值
this.objLink.a= ...
// 不允许@ObjectLink装饰的数据自身赋值
this.objLink= ...
说明
@ObjectLink
装饰的变量不能被赋值,如果要使用赋值操作,请使用@Prop
。
@ObjectLink传递/访问 | 说明 |
---|---|
从父组件初始化 | 必须指定。初始化@ObjectLink装饰的变量必须同时满足以下场景:类型必须是@Observed装饰的class。初始化的数值需要是数组项,或者class的属性。同步源的class或者数组必须是@State,@Link,@Provide,@Consume或者@ObjectLink装饰的数据。 |
与源对象同步 | 双向。 |
可以初始化子组件 | 允许,可用于初始化常规变量、@State、@Link、@Prop、@Provide |
初始化规则图示
观察的变化
@Observed
装饰的类,如果其属性为非简单类型,比如class
、Object
或者数组,也需要被@Observed
装饰,否则将观察不到其属性的变化。
class ClassA {
public c: number;
constructor(c: number) {
this.c = c;
}
}
@Observed
class ClassB {
public a: ClassA;
public b: number;
constructor(a: ClassA, b: number) {
this.a = a;
this.b = b;
}
}
以上示例中,ClassB被@Observed装饰,其成员变量的赋值的变化是可以被观察到的,但对于ClassA,没有被@Observed装饰,其属性的修改不能被观察到。
@ObjectLink b: ClassB
// 赋值变化可以被观察到
this.b.a = new ClassA(5)
this.b.b = 5
// ClassA没有被@Observed装饰,其属性的变化观察不到
this.b.a.c = 5
@ObjectLink:@ObjectLink只能接收被@Observed装饰class的实例,可以观察到:
1.初始渲染: