HarmonyOS ArkTS 状态管理 V2:@Monitor 实战详解

45 阅读3分钟

HarmonyOS ArkTS 状态管理 V2:@Monitor 实战详解

一起来构建生态吧~

在 ArkTS 状态管理 V2 中,@Monitor 是一个非常容易被低估、但在真实业务中极其重要的装饰器。 它解决的不是“UI 更新”,而是—— “状态变化后,我要做什么”


一、@Monitor 是用来干什么的?

在 ArkTS 中:

  • @Local / @Param / @ObservedV2负责状态
  • UI 自动刷新 → 由框架完成
  • ❓ 那副作用逻辑(日志、校验、联动、请求)怎么办?

这正是 @Monitor 的职责:

监听一个或多个状态变化,并在变化完成后执行逻辑


二、@Monitor 能做什么?

@Monitor 可以:

  • ✅ 监听 一个或多个状态
  • ✅ 监听 深层对象属性
  • ✅ 拿到 变化前 / 变化后 的值
  • ✅ 聚合多次变化,只触发一次回调

它是 V2 中对旧 @Watch 的全面升级。


三、最小可用示例(从 0 到 1)

示例目标

点击按钮 → 修改状态 → 自动触发监听 → 拿到 before / after


组件代码

 @ComponentV2
 struct CounterPage {
   @Local count: number = 0;
 ​
   @Monitor("count")
   onCountChanged(monitor: IMonitor) {
     const { before, now } = monitor.value("count")!;
     console.log(`count 变化:${before} → ${now}`);
   }
 ​
   build() {
     Column({ space: 16 }) {
       Text(`当前值:${this.count}`)
         .fontSize(20)
 ​
       Button("➕ 增加")
         .onClick(() => {
           this.count++;
         })
     }
     .padding(20)
   }
 }

执行效果

  • 初始:count = 0

  • 点击按钮:

    • count 变为 1
    • @Monitor 被触发
    • 控制台输出:
 count 变化:0 → 1

四、状态变化执行流程(图解)

 flowchart TD
     A[用户点击按钮] --> B[count 自增]
     B --> C[ArkTS 计算新状态]
     C --> D[UI 自动刷新]
     D --> E[@Monitor 收集变化]
     E --> F[触发 onCountChanged 回调]

重点 @Monitor 是在 状态稳定后** 执行,而不是“边改边触发”。


五、实战场景一:监听多个状态

场景说明

表单页面中,只要「用户名 或 年龄」变化,就重新校验数据


示例代码

 @ComponentV2
 struct ProfileForm {
   @Local name: string = "";
   @Local age: number = 0;
 ​
   @Monitor("name", "age")
   onFormChanged(monitor: IMonitor) {
     if (monitor.value("name")) {
       console.log("name 发生变化");
     }
     if (monitor.value("age")) {
       console.log("age 发生变化");
     }
   }
 ​
   build() {
     Column() {
       TextInput({ placeholder: "姓名" })
         .onChange(v => this.name = v)
 ​
       TextInput({ placeholder: "年龄" })
         .onChange(v => this.age = Number(v))
     }
   }
 }

关键点

  • 多个状态变化 → 只触发一次监听
  • 在回调中判断 哪些字段发生了变化

六、实战场景二:监听深层对象(重点)

场景说明

用户信息是一个对象,只要 name / age 改变,就触发逻辑


定义响应式类

 @ObservedV2
 class User {
   @Trace name: string = "";
   @Trace age: number = 0;
 }

组件监听深层字段

 @ComponentV2
 struct UserPage {
   @Local user: User = new User();
 ​
   @Monitor("user.name", "user.age")
   onUserChanged(monitor: IMonitor) {
     console.log("用户信息变化:", monitor);
   }
 ​
   build() {
     Column() {
       Button("修改姓名")
         .onClick(() => {
           this.user.name = "张三";
         })
 ​
       Button("修改年龄")
         .onClick(() => {
           this.user.age++;
         })
     }
   }
 }

监听原理图

 flowchart LR
     A[user.name 改变] --> B[@Trace 捕获变化]
     B --> C[@ObservedV2 通知系统]
     C --> D[@Monitor 监听到路径变化]
     D --> E[执行监听回调]

七、常见误区(非常重要)

误区 1:监听普通对象内部字段

 @Local user = { name: "A" };
 ​
 // ❌ 不会触发
 this.user.name = "B";

正确方式:

  • 整体替换对象
  • 或使用 @ObservedV2 + @Trace

误区 2:把 @Monitor 当成 UI 刷新工具

UI 刷新 ≠ @Monitor

  • UI 刷新 → 框架自动完成
  • @Monitor业务副作用

八、什么时候一定要用 @Monitor

推荐使用场景:

  • 表单校验
  • 日志上报
  • 自动保存
  • 状态联动(A 变 → 改 B)
  • 调试复杂状态变化

不推荐:

  • 单纯为了更新 UI
  • 高频、无逻辑的状态变化

🏁 九、总结一句话版

@Monitor 是 ArkTS V2 中的「状态变化监听器」, 用来处理“状态变了之后要做什么”,而不是“怎么刷新 UI”。

它和以下装饰器的关系非常清晰:

装饰器职责
@Local / @Param状态本身
@ObservedV2 + @Trace深度响应
@Monitor状态变化后的逻辑