@Param:组件外部输入
developer.huawei.com/consumer/cn…
@Param表示组件从外部传入的状态,使得父子组件之间的数据能够进行同步
转换前
ts 代码解读复制代码/**
*
* ParamCmp.ets
* Created by unravel on 2024/6/18
* @abstract
*/
@ObservedV2
class Region {
@Trace x: number;
@Trace y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
@ObservedV2
class Info {
@Trace name: string;
@Trace age: number;
@Trace region: Region;
constructor(name: string, age: number, x: number, y: number) {
this.name = name;
this.age = age;
this.region = new Region(x, y);
}
}
@ComponentV2
export struct ParamCmp {
@Local infoList: Info[] = [new Info("Alice", 8, 0, 0), new Info("Barry", 10, 1, 20), new Info("Cindy", 18, 24, 40)];
build() {
Column() {
ForEach(this.infoList, (info: Info) => {
MiddleComponent({ info: info })
})
Button("change")
.onClick(() => {
this.infoList[0] = new Info("Atom", 40, 27, 90);
this.infoList[1].name = "Bob";
this.infoList[2].region = new Region(7, 9);
})
}
}
}
@ComponentV2
struct MiddleComponent {
@Require @Param info: Info;
build() {
Column() {
Text(`name: ${this.info.name}`)
Text(`age: ${this.info.age}`)
SubComponent({ region: this.info.region })
}
}
}
@ComponentV2
struct SubComponent {
@Require @Param region: Region;
build() {
Column() {
Text(`region: ${this.region.x}-${this.region.y}`)
}
}
}
转换后
ts 代码解读复制代码if (!("finalizeConstruction" in ViewPU.prototype)) {
Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
/**
*
* ParamCmp.ets
* Created by unravel on 2024/6/18
* @abstract
*/
@ObservedV2
class Region {
@Trace
x: number;
@Trace
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
@ObservedV2
class Info {
@Trace
name: string;
@Trace
age: number;
@Trace
region: Region;
constructor(name: string, age: number, x: number, y: number) {
this.name = name;
this.age = age;
this.region = new Region(x, y);
}
}
export class ParamCmp extends ViewV2 {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
super(parent, elmtId, extraInfo);
this.infoList = [new Info("Alice", 8, 0, 0), new Info("Barry", 10, 1, 20), new Info("Cindy", 18, 24, 40)];
this.finalizeConstruction();
}
@Local
infoList: Info[];
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
ForEach.create();
const forEachItemGenFunction = _item => {
const info = _item;
{
this.observeComponentCreation2((elmtId, isInitialRender) => {
if (isInitialRender) {
let componentCall = new MiddleComponent(this, { info: info }, undefined, elmtId, () => { }, { page: "entry/src/main/ets/pages/statev2/ParamCmp.ets", line: 38 });
ViewV2.create(componentCall);
let paramsLambda = () => {
return {
info: info
};
};
componentCall.paramsGenerator_ = paramsLambda;
}
else {
this.updateStateVarsOfChildByElmtId(elmtId, {
info: info
});
}
}, { name: "MiddleComponent" });
}
};
this.forEachUpdateFunction(elmtId, this.infoList, forEachItemGenFunction);
}, ForEach);
ForEach.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel("change");
Button.onClick(() => {
this.infoList[0] = new Info("Atom", 40, 27, 90);
this.infoList[1].name = "Bob";
this.infoList[2].region = new Region(7, 9);
});
}, Button);
Button.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
class MiddleComponent extends ViewV2 {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
super(parent, elmtId, extraInfo);
this.initParam("info", (params && "info" in params) ? params.info : undefined);
this.finalizeConstruction();
}
@Param
readonly info: Info;
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`name: ${this.info.name}`);
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`age: ${this.info.age}`);
}, Text);
Text.pop();
{
this.observeComponentCreation2((elmtId, isInitialRender) => {
if (isInitialRender) {
let componentCall = new SubComponent(this, { region: this.info.region }, undefined, elmtId, () => { }, { page: "entry/src/main/ets/pages/statev2/ParamCmp.ets", line: 58 });
ViewV2.create(componentCall);
let paramsLambda = () => {
return {
region: this.info.region
};
};
componentCall.paramsGenerator_ = paramsLambda;
}
else {
this.updateStateVarsOfChildByElmtId(elmtId, {
region: this.info.region
});
}
}, { name: "SubComponent" });
}
Column.pop();
}
public updateStateVars(params) {
if (params === undefined) {
return;
}
if ("info" in params) {
this.updateParam("info", params.info);
}
}
rerender() {
this.updateDirtyElements();
}
}
class SubComponent extends ViewV2 {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
super(parent, elmtId, extraInfo);
this.initParam("region", (params && "region" in params) ? params.region : undefined);
this.finalizeConstruction();
}
@Param
readonly region: Region;
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`region: ${this.region.x}-${this.region.y}`);
}, Text);
Text.pop();
Column.pop();
}
public updateStateVars(params) {
if (params === undefined) {
return;
}
if ("region" in params) {
this.updateParam("region", params.region);
}
}
rerender() {
this.updateDirtyElements();
}
}
对比
代码转换前后没有太大的变化,@Param装饰的属性变成了readonly的。即我们只能访问@Param变量和它的属性,不能对@Param属性进行重新赋值
Param装饰器
和@Trace、@Local的实现很相似。只是限制了@Param只能调用get不能调用set
关于trackInternal的实现参考 鸿蒙ACE-V2状态分析@ObservedV2、@Trace装饰器
评论记录:
回复评论: