@Monitor 装饰器 — ArkTS 状态监听详解

31 阅读4分钟

@Monitor 装饰器 — ArkTS 状态监听详解

一起来构建生态吧~

在 HarmonyOS ArkTS 状态管理 V2 中,@Monitor 是一个 用于监听状态变量变化的装饰器,它可以检测状态的深层变化并触发回调。相比旧版本的 @Watch,它支持更丰富的监听场景,并能获取变化前后数据。华为开发者官网+1


一、为什么需要 @Monitor

在使用组件状态(如 @Local, @Param@ObservedV2 + @Trace)时,我们往往不仅希望让 UI 自动更新,还希望:

  • 监听某个状态变化并运行逻辑
  • 知道状态变化前后的值;
  • 监听多个状态或深层嵌套属性。

这时 @Monitor 就非常有用,它是 V2 状态体系中更强大的监听工具华为开发者官网


二、核心作用

@Monitor 的作用:

  1. 监听指定状态变量的变化
  2. 支持监听多个状态路径;
  3. 可获取每个被监听属性的“变化前 vs 变化后”值;
  4. 适用于组件内部状态(例如 @Local, @Param)或深度对象属性(例如 @ObservedV2/@Trace 类)。华为开发者官网

三、基本语法格式

你在组件内部定义一个方法,并用 @Monitor 标记要监听的一个或多个状态路径。

 @Monitor("stateA", "stateB.subField")
 onStateChanged(monitor: IMonitor) {
   // 当 stateA 或 stateB.subField 有变化时执行
 }

@Monitor 的参数是一个或多个要监听的状态表达式华为开发者官网


四、工作机制与触发时机

当监听的状态属性值发生变化时

  1. 将先前的“旧值”与当前的新值比较;
  2. 聚合所有变化路径(例如 stateA, stateB.subField 等);
  3. 触发标记了 @Monitor 的回调方法;
  4. 回调获取一个监听元信息(类似 IMonitor)对象;
  5. 你可以从这个对象中按属性路径查询“旧值 vs 新值”。华为开发者官网

重要说明:

  • @Monitor 是在 V2 状态体系下监听状态变化的正式机制
  • 比旧的 @Watch 更加强大;
  • 若某个监听属性在一次交互内多次结果发生改动,回调只在最终状态总结后触发一次(聚合触发)华为开发者官网

五、实际典型使用场景

1) 监听简单状态

 @ComponentV2
 struct Example {
   @Local count: number = 0;
 ​
   @Monitor("count")
   onCountChange(monitor: IMonitor) {
     const { before, now } = monitor.value("count")!;
     console.log(`Count changed: ${before}${now}`);
   }
 ​
   build() {
     Button("Add").onClick(() => { this.count++; });
   }
 }

count 发生变化时,onCountChange 会被调用,你可以获取变化前后的值。华为开发者官网


2) 同时监听多个状态

 @ComponentV2
 struct MultiWatch {
   @Local a: string = "";
   @Local b: number = 0;
 ​
   @Monitor("a", "b")
   onAnyChange(monitor: IMonitor) {
     // monitor.value("a"), monitor.value("b")
   }
 }

如果 ab 任意一个状态发生变化,监听回调都将被触发。华为开发者官网


3) 深层嵌套类/对象属性监听

对于深层嵌套状态(如使用 @ObservedV2/@Trace 监听的对象):

 @ObservedV2
 class Profile {
   @Trace name = "";
   @Trace age = 0;
 }
 ​
 @ComponentV2
 struct Demo {
   @Local profile = new Profile();
 ​
   @Monitor("profile.name", "profile.age")
   onProfileChange(monitor: IMonitor) {
     // 使用 monitor.value("profile.name") 和 monitor.value("profile.age")
   }
 }

只要某个子属性实际变化,就会触发监听回调。华为开发者官网


六、与旧版监听机制对比

特性旧版 @Watch新版 @Monitor
监听单一变量✔️✔️
监听多个变量✔️
获取变化前值✔️
深层嵌套属性✔️
在类与组件里使用❌ 受限✔️ 更灵活

监控能力和语义更强是 @Monitor 最大优势。华为开发者官网


七、使用注意与最佳实践

推荐用于:

  • 想精确监听状态变化并执行逻辑;
  • 想获取前后状态值;
  • 想跨多个状态统一响应逻辑。

注意:

  • 监听路径必须是有效的状态变量路径;
  • 与旧 V1 状态装饰器需配合 V2 体系一起使用;
  • 对深层监听,需要配合 @ObservedV2 + @Trace 才能监听对象内部状态。华为开发者官网

八、总结