鸿蒙ACE-V2状态分析@Computed

134 阅读1分钟

@Computed装饰器:计算属性

developer.huawei.com/consumer/cn… @Computed为方法装饰器,装饰getter方法。@Computed会检测被计算的属性变化,当被计算的属性变化时,@Computed只会被求解一次

转换前

/**
 *
 * ComputedCmp.ets
 * Created by unravel on 2024/6/18
 * @abstract
 */

@ComponentV2
export struct ComputedCmp {
  @Local celsius: number = 20;

  @Computed
  get fahrenheit(): number {
    return this.celsius * 9 / 5 + 32; // C -> F
  }

  @Computed
  get kelvin(): number {
    return (this.fahrenheit - 32) * 5 / 9 + 273.15; // F -> K
  }

  @Monitor("kelvin")
  onKelvinMonitor(mon: IMonitor) {
    console.log("kelvin changed from " + mon.value()?.before + " to " + mon.value()?.now);
  }

  build() {
    Column({ space: 20 }) {
      Row({ space: 20 }) {
        Button('-')
          .onClick(() => {
            this.celsius--;
          })

        Text(`Celsius ${this.celsius.toFixed(1)}`).fontSize(50)

        Button('+')
          .onClick(() => {
            this.celsius++;
          })
      }

      Text(`Fahrenheit ${this.fahrenheit.toFixed(2)}`).fontSize(50)
      Text(`Kelvin ${this.kelvin.toFixed(2)}`).fontSize(50)
    }
    .width('100%')
  }
}

转换后

if (!("finalizeConstruction" in ViewPU.prototype)) {
    Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
export class ComputedCmp extends ViewV2 {
    constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
        super(parent, elmtId, extraInfo);
        this.celsius = 20;
        this.finalizeConstruction();
    }
    @Local
    celsius: number;
    @Computed
    get fahrenheit(): number {
        return this.celsius * 9 / 5 + 32; // C -> F
    }
    @Computed
    get kelvin(): number {
        return (this.fahrenheit - 32) * 5 / 9 + 273.15; // F -> K
    }
    @Monitor("kelvin")
    onKelvinMonitor(mon: IMonitor) {
        console.log("kelvin changed from " + mon.value()?.before + " to " + mon.value()?.now);
    }
    initialRender() {
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Column.create({ space: 20 });
            Column.width('100%');
        }, Column);
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Row.create({ space: 20 });
        }, Row);
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Button.createWithLabel('-');
            Button.onClick(() => {
                this.celsius--;
            });
        }, Button);
        Button.pop();
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Text.create(`Celsius ${this.celsius.toFixed(1)}`);
            Text.fontSize(50);
        }, Text);
        Text.pop();
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Button.createWithLabel('+');
            Button.onClick(() => {
                this.celsius++;
            });
        }, Button);
        Button.pop();
        Row.pop();
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Text.create(`Fahrenheit ${this.fahrenheit.toFixed(2)}`);
            Text.fontSize(50);
        }, Text);
        Text.pop();
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Text.create(`Kelvin ${this.kelvin.toFixed(2)}`);
            Text.fontSize(50);
        }, Text);
        Text.pop();
        Column.pop();
    }
    rerender() {
        this.updateDirtyElements();
    }
}

Computed装饰器

Computed 是一个getter装饰器。

有@Computed装饰器的类的对象会有一个watchProp属性,这个属性是一个对象,对象里的每个属性是@Computed装饰的属性名,对应的值是@Computed装饰的计算函数

可以看到Computed和Monitor非常类似

image.png