@Local装饰器:组件内部状态
developer.huawei.com/consumer/cn…
@Local表示组件内部的状态,使得自定义组件内部的变量具有观测变化的能力
转换前
ts 代码解读复制代码/**
*
* LocalCmp.ets
* Created by unravel on 2024/6/18
* @abstract
*/
@ObservedV2
class Info {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
@ComponentV2
export struct LocalCmp {
info1: Info = new Info("Tom", 25);
@Local info2: Info = new Info("Tom", 25);
build() {
Column() {
Text(`info1: ${this.info1.name}-${this.info1.age}`) // Text1
Text(`info2: ${this.info2.name}-${this.info2.age}`) // Text2
Button("change info1&info2")
.onClick(() => {
this.info1 = new Info("Lucy", 18); // Text1不会刷新
this.info2 = new Info("Lucy", 18); // Text2会刷新
})
}
}
}
转换后
ts 代码解读复制代码if (!("finalizeConstruction" in ViewPU.prototype)) {
Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
/**
*
* LocalCmp.ets
* Created by unravel on 2024/6/18
* @abstract
*/
@ObservedV2
class Info {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
export class LocalCmp extends ViewV2 {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
super(parent, elmtId, extraInfo);
this.info1 = "info1" in params ? params.info1 : new Info("Tom", 25);
this.info2 = new Info("Tom", 25);
this.finalizeConstruction();
}
info1: Info;
@Local
info2: Info;
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
Column.debugLine("entry/src/main/ets/pages/statev2/LocalCmp.ets(24:5)");
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`info1: ${this.info1.name}-${this.info1.age}`);
Text.debugLine("entry/src/main/ets/pages/statev2/LocalCmp.ets(25:7)");
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`info2: ${this.info2.name}-${this.info2.age}`);
Text.debugLine("entry/src/main/ets/pages/statev2/LocalCmp.ets(26:7)");
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel("change info1&info2");
Button.debugLine("entry/src/main/ets/pages/statev2/LocalCmp.ets(27:7)");
Button.onClick(() => {
this.info1 = new Info("Lucy", 18); // Text1不会刷新
this.info2 = new Info("Lucy", 18); // Text2会刷新
});
}, Button);
Button.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
差异
转换前后装饰器没有任何变化。我们还是从装饰器源码看吧
Local装饰器
可以看到Local装饰器和Trace装饰器都是使用trackInternal实现。唯一的不同是Local和Trace在编译期做了不同的限制
Local被限制在只能在ComponentV2组件内使用
Trace被限制在只能在ObservedV2装饰的类中使用
关于trackInternal的实现参考 鸿蒙ACE-V2状态分析@ObservedV2、@Trace
评论记录:
回复评论: