@Once:初始化同步一次
developer.huawei.com/consumer/cn…
@Once装饰器仅在变量初始化时接受外部传入值进行初始化,当后续数据源更改时,不会将修改同步给子组件
转换前
/**
*
* OnceCmp.ets
* Created by unravel on 2024/6/18
* @abstract
*/
@ComponentV2
struct CompA {
@Param @Once onceParam: string = '';
build() {
Column() {
Text(`onceParam: ${this.onceParam}`)
}
}
}
@ComponentV2
export struct OnceCmp {
@Local message: string = "Hello World";
build() {
Column() {
Text(`Parent message: ${this.message}`)
Button("change message")
.onClick(() => {
this.message = "Hello Tomorrow";
})
CompA({ onceParam: this.message })
}
}
}
转换后
if (!("finalizeConstruction" in ViewPU.prototype)) {
Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
class CompA extends ViewV2 {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
super(parent, elmtId, extraInfo);
this.initParam("onceParam", (params && "onceParam" in params) ? params.onceParam : '');
this.finalizeConstruction();
}
@Param
@Once
onceParam: string;
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`onceParam: ${this.onceParam}`);
}, Text);
Text.pop();
Column.pop();
}
public updateStateVars(params) {
if (params === undefined) {
return;
}
if ("onceParam" in params) {
this.updateParam("onceParam", params.onceParam);
}
}
rerender() {
this.updateDirtyElements();
}
}
export class OnceCmp extends ViewV2 {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
super(parent, elmtId, extraInfo);
this.message = "Hello World";
this.finalizeConstruction();
}
@Local
message: string;
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`Parent message: ${this.message}`);
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel("change message");
Button.onClick(() => {
this.message = "Hello Tomorrow";
});
}, Button);
Button.pop();
{
this.observeComponentCreation2((elmtId, isInitialRender) => {
if (isInitialRender) {
let componentCall = new CompA(this, { onceParam: this.message }, undefined, elmtId, () => { }, { page: "entry/src/main/ets/pages/statev2/OnceCmp.ets", line: 29 });
ViewV2.create(componentCall);
let paramsLambda = () => {
return {
onceParam: this.message
};
};
componentCall.paramsGenerator_ = paramsLambda;
}
else {
this.updateStateVarsOfChildByElmtId(elmtId, {
onceParam: this.message
});
}
}, { name: "CompA" });
}
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}}
差异
转换前后装饰器没有任何变化。我们还是从装饰器源码看吧
Once装饰器
可以看到Once装饰器很简单,只是在对象的元数据上添加了@once
public static addParamVariableDecoMeta(proto: Object, varName: string, deco?: string, deco2?: string): void
其中meta[varName] 只有不存在的时候才赋值了一个空对象。这是因为它需要和@Param联合使用
@param赋值给deco,@once赋值给deco2