鸿蒙ACE-V2状态分析@Monitor

124 阅读1分钟

@Monitor装饰器:状态变量修改监听

developer.huawei.com/consumer/cn…

@Monitor装饰器用于监听状态变量修改,使得状态变量具有深度监听的能力

转换前

/**
 *
 * MonitorCmp.ets
 * Created by unravel on 2024/6/18
 * @abstract
 */
@ObservedV2
class Info {
  @Trace name: string = "Tom";
  @Trace region: string = "North";
  @Trace job: string = "Teacher";
  age: number = 25;

  // name被@Trace装饰,能够监听变化
  @Monitor("name")
  onNameChange(monitor: IMonitor) {
    console.log(`name change from ${monitor.value()?.before} to ${monitor.value()?.now}`);
  }

  // age未被@Trace装饰,不能监听变化
  @Monitor("age")
  onAgeChange(monitor: IMonitor) {
    console.log(`age change from ${monitor.value()?.before} to ${monitor.value()?.now}`);
  }

  // region与job均被@Trace装饰,能够监听变化
  @Monitor("region", "job")
  onChange(monitor: IMonitor) {
    monitor.dirty.forEach((path: string) => {
      console.log(`${path} change from ${monitor.value(path)?.before} to ${monitor.value(path)?.now}`);
    })
  }
}

@ComponentV2
export struct MonitorCmp {
  info: Info = new Info();

  build() {
    Column() {
      Button("change name")
        .onClick(() => {
          this.info.name = "Jack"; // 能够触发onNameChange方法
        })
      Button("change age")
        .onClick(() => {
          this.info.age = 26; // 不能够触发onAgeChange方法
        })
      Button("change region")
        .onClick(() => {
          this.info.region = "South"; // 能够触发onChange方法
        })
      Button("change job")
        .onClick(() => {
          this.info.job = "Driver"; // 能够触发onChange方法
        })
    }
  }
}

转换后

if (!("finalizeConstruction" in ViewPU.prototype)) {
    Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
/**
 *
 * MonitorCmp.ets
 * Created by unravel on 2024/6/18
 * @abstract
 */
@ObservedV2
class Info {
    @Trace
    name: string = "Tom";
    @Trace
    region: string = "North";
    @Trace
    job: string = "Teacher";
    age: number = 25;
    // name被@Trace装饰,能够监听变化
    @Monitor("name")
    onNameChange(monitor: IMonitor) {
        console.log(`name change from ${monitor.value()?.before} to ${monitor.value()?.now}`);
    }
    // age未被@Trace装饰,不能监听变化
    @Monitor("age")
    onAgeChange(monitor: IMonitor) {
        console.log(`age change from ${monitor.value()?.before} to ${monitor.value()?.now}`);
    }
    // region与job均被@Trace装饰,能够监听变化
    @Monitor("region", "job")
    onChange(monitor: IMonitor) {
        monitor.dirty.forEach((path: string) => {
            console.log(`${path} change from ${monitor.value(path)?.before} to ${monitor.value(path)?.now}`);
        });
    }
}
export class MonitorCmp extends ViewV2 {
    constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
        super(parent, elmtId, extraInfo);
        this.info = "info" in params ? params.info : new Info();
        this.finalizeConstruction();
    }
    info: Info;
    initialRender() {
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Column.create();
        }, Column);
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Button.createWithLabel("change name");
            Button.onClick(() => {
                this.info.name = "Jack"; // 能够触发onNameChange方法
            });
        }, Button);
        Button.pop();
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Button.createWithLabel("change age");
            Button.onClick(() => {
                this.info.age = 26; // 不能够触发onAgeChange方法
            });
        }, Button);
        Button.pop();
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Button.createWithLabel("change region");
            Button.onClick(() => {
                this.info.region = "South"; // 能够触发onChange方法
            });
        }, Button);
        Button.pop();
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Button.createWithLabel("change job");
            Button.onClick(() => {
                this.info.job = "Driver"; // 能够触发onChange方法
            });
        }, Button);
        Button.pop();
        Column.pop();
    }
    rerender() {
        this.updateDirtyElements();
    }
}

Monitor装饰器

Monitor是一个方法装饰器。

有@Monitor装饰器的类的对象会有一个watchProp属性,这个属性是一个对象,对象里的每个属性是@Monitor中参数按照空格拼接的传,对应的值是@Monitor装饰的回调函数

image.png