鸿蒙应用开发:@Monitor 装饰器使用教程

这是一个使用鸿蒙技术开发的本地原生记账应用,非常适合大家用来练手。相关源码已上传至 Github,点击此处查看项目。欢迎大家交流、指正,也欢迎提交 PR。

一、引言

在鸿蒙(HarmonyOS)应用开发中,状态管理是构建动态用户界面的核心。随着 状态管理 V2 的推出,@Monitor 装饰器为开发者提供了一种更精细、更灵活的状态变化监听机制。本文将深入介绍 @Monitor 的基本用法、高级特性以及实际应用场景,帮助你更好地掌控应用状态。

二、@Monitor 装饰器简介

@Monitor 是状态管理 V2 中的装饰器,用于监听组件内或 @ObservedV2 装饰类中状态变量的变化。当被监听的状态变量发生改变时,会自动触发被 @Monitor 装饰的回调函数执行。这使得开发者能够精确地响应特定数据的变化,而无需在多个地方手动检查状态。

三、基本语法

@Monitor 的基本语法如下:

typescript 复制代码
@Monitor('path')
onValueChange(monitor: IMonitor) {
  // 处理变化逻辑
}
  • 监听路径 :@Monitor 接受一个或多个字符串参数,用于指定要监听的状态变量路径。
  • 回调函数 :被 @Monitor 装饰的函数,其参数 monitor: IMonitor 提供了变化前后的值、脏数据路径等信息。

3.1 监听多个变量

支持同时监听多个变量,用逗号分隔:

typescript 复制代码
@Monitor('prop1', 'prop2')
onMultiChange(monitor: IMonitor) {
  // 处理 prop1 或 prop2 的变化
}

3.2 深层属性监听

支持深层属性监听,使用点号连接:

typescript 复制代码
@Monitor('obj.prop')
onDeepChange(monitor: IMonitor) {
  // 处理 obj.prop 的变化
}

四、使用示例

以下示例展示如何监听对象属性的变化,并在回调中获取变化前后的值:

typescript 复制代码
@ObservedV2
class Book {
  @Trace num: number = 0;
  name: string = '时间简史';
}

@Entry
@ComponentV2
struct SceneTwo {
  @Local book: Book = new Book();

  @Monitor('book.num', 'book.name')
  change(monitor: IMonitor) {
    monitor.dirty.forEach((path: string) => {
      console.info(`监听${path}属性的变化,变之前的值:${JSON.stringify(monitor.value(path)?.before)},变后的值:${JSON.stringify(monitor.value(path)?.now)}。`);
    });
  }

  build() {
    Column() {
      Text(`Name: ${this.book.name}`)
        .width(320)
        .margin(10)
        .fontSize(20)
        .textAlign(TextAlign.Center);
      Text(`Index: ${this.book.num}`)
        .width(320)
        .margin(10)
        .fontSize(20)
        .textAlign(TextAlign.Center);
      Button('change')
        .width(320)
        .margin(10)
        .onClick(() => {
          this.book.num++;
          this.book.name += '1';
        });
    }
  }
}

在这个示例中:

  • Book 类被 @ObservedV2 装饰,其属性 num 被 @Trace 装饰,使其成为可观察状态。
  • 组件 SceneTwo 中,@Monitor('book.num', 'book.name') 同时监听了 book.num 和 book.name 两个属性的变化。
  • 当点击按钮时,book.num 和 book.name 发生变化,change 回调函数被触发,并通过 monitor.dirty 获取所有发生变化的路径,进而获取变化前后的值。

运行效果:

4.1 去掉 book.num 监听后的行为

如果将 @Monitor 的参数改为只监听 book.name:

typescript 复制代码
@Monitor('book.name')
change(monitor: IMonitor) {
  // ...
}

此时,当点击按钮触发 this.book.num++ 时,change 回调不会被触发 ;而 this.book.name += '1' 同样不会触发回调。

原因分析 :@Monitor 的监听机制是精确路径匹配 的,且被监听的对象属性必须被 @Trace 装饰才能被精确监听。在示例中,book.name 属性没有使用 @Trace 装饰,因此 @Monitor('book.name') 无法监听到 name 属性的变化。这体现了 @Monitor 的精细化控制 能力------开发者需要配合 @Trace 装饰器,才能精确监听特定属性的变化,避免不必要的回调执行,从而提升应用性能。

运行效果:

五、注意事项

在使用 @Monitor 时,需要注意以下几点:

  • @Trace 装饰 :被监听的对象属性必须 被 @Trace 装饰,否则 @Monitor 无法监听到该属性的变化。未使用 @Trace 的属性即使被 @Monitor 监听,也不会触发回调。
  • 异步执行 :@Monitor 是异步执行的,与 animateTo 等动效存在冲突时,可使用 UIUtils.applySync 等接口解决。
  • 路径写法 :在 @ObservedV2 装饰的类中,@Monitor 传入属性名即可;在组件中需传入 "变量名.属性名" 实现深层监听。

六、总结

@Monitor 装饰器是鸿蒙状态管理 V2 中一个强大而灵活的工具,它让开发者能够以声明式的方式精确监听状态变化,从而编写出更清晰、更高效的响应式代码。

通过合理运用 @Monitor,你可以更好地控制应用的数据流,提升用户体验。

相关推荐
修炼的dance14 分钟前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M21 分钟前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写23 分钟前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李24 分钟前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易38 分钟前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马1 小时前
前沿视界
前端
kyriewen1 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易1 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员
IT_陈寒1 小时前
Vue的这个响应式陷阱,差点让我加班到天亮
前端·人工智能·后端
Flynt3 小时前
别写拖拽行为,只声明"能拖到哪":UIST 最佳论文的拖拽方案我实测了
前端·svg·preact