0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HarmonyOS Next V2 @Monitor 和@Computed

万少 来源:jf_22972444 作者:jf_22972444 2025-04-02 18:26 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

HarmonyOS Next V2 @Monitor 和@Computed

@Monitor 介绍

@Monitor 是状态把管理 V2 版本中的用于监听状态变量修改的技术。

它可以直接用在

  1. @ComponentV2装饰的自定义组件中,用于被@Local@Param@Provider@Comsumer@Computed修饰的状态变量中
  2. 对于深层次的数据,如深层次对象、对象数组等,需要搭配@ObservedV2@Trace一起使用。
  3. 可以同时监听多个属性
  4. 可以获取到监听属性的修改前后的数据变化

对比状态管理 V1 中的@Watch

@Monitor@Watch功能要强大不少

  1. @Watch 不能用在@ComponentV2修饰的
  2. @Watch 不具备深度监听的功能
  3. @Watch 无法同时监听多个属性
  4. @Watch 无法检测 属性修改前后的变化

@Monitor 监听单个属性

@Entry
@ComponentV2
struct Index {
  @Local num: number = 100

  @Monitor("num")
  changeNum() {
    console.log("检测到数据的修改啦")
  }

  build() {
    Column() {

      Button(`点击修改 ${this.num}`)
        .onClick(() = > {
          this.num++
        })
    }
    .width("100%")
    .height("100%")
  }
}

@Monitor 同时监听多个属性

@Entry
@ComponentV2
struct Index {
  @Local num: number = 100
  @Local age: number = 200

  // 同时监听多个状态的修改
  @Monitor("num","age")
  changeNum() {
    console.log("检测到数据的修改啦")
  }

  build() {
    Column() {
      Button(`点击修改 num ${this.num}`)
        .onClick(() = > {
          this.num++
        })
      Button(`点击修改 age ${this.age}`)
        .onClick(() = > {
          this.age++
        })
    }
    .width("100%")
    .height("100%")
  }
}

@Monitor 的回调函数

@Monitor 的回调函数可以给我们提供这样的能力:

  1. 如果监听了多个状态,而只有一个状态发生变化时, 可以给获知到具体哪个状态发生了变化
  2. 当状态发生变化时,可以获取到变化前后的两个值

@Monitor 的回调函数的参数是 [IMonitor],它是一个对象,拥有两个属性

  1. dirty ,是一个字符串数组,里面存放了修改的状态的名称
  2. value,是一个函数,调用返回会返回一个新的对象,新对象中包含了 path:修改的状态的名称,before:修改前的数据,now:修改后的数据,另外 value() 调用时,如果不传递参数并且你是同时修改多个状态的话,那么它只会返回第一个状态,如果传递了参数-状态变量 那么就会返回该状态变量的相关信息
@Entry
@ComponentV2
struct Index {
  @Local num: number = 100
  @Local age: number = 200

  // 同时监听多个状态的修改
  @Monitor("num","age")
  changeNum(Monitor: IMonitor) {
    console.log("修改的状态", Monitor.dirty)
    console.log("Monitor.value()", JSON.stringify(Monitor.value("age")))

  }

  build() {
    Column() {
      Button(`同时修改 num 和 age ${this.num}  ${this.age}`)
        .onClick(() = > {
          this.num++
          this.age++
        })

    }
    .width("100%")
    .height("100%")
  }
}

@Monitor 深度监听

@Monitor 需要和 @ObservedV2@Trace一起使用才能实现深度监听的效果,需要注意的是:

  1. @Monitor可以直接写在 @ObserveV2 修饰的class
  2. @Monitor 也可以写在正常的组件内
@ObservedV2
class Person {
  @Trace son: Son = new Son()
}

@ObservedV2
class Son {
  // @Monitor可以直接写在 @ObserveV2 修饰的class中
  @Monitor("weight")
  weightChange() {
    console.log("1 儿子的体重修改了")
  }

  @Trace weight: number = 200
}


@Entry
@ComponentV2
struct Index {
  person: Person = new Person()
    // @Monitor 也可以写在正常的组件内
  @Monitor("person.son.weight")
  weightChange() {
    console.log("2 儿子的体重呗修改了")
  }

  build() {
    Column() {
      Button(`修改儿子的体重${this.person.son.weight}`)
        .onClick(() = > {
          this.person.son.weight++
        })
    }
    .width("100%")
    .height("100%")
  }
}

@Monitor 的限制

在实际开发使用中,@Monitor也存在一些限制,无法监听内置类型(ArrayMapDateSet)的 API 调用引起的变化,如当你检测整个数组时,你对数组使用 pushsplice等常见方法修改数组,是无法检测到的。当然,当整个数组被重新赋值时,可以检测到它的变化

@ObservedV2
class Person {
  @Trace name: string = "小明"
}


@Entry
@ComponentV2
struct Index {
  @Local
  personList: Person[] = [new Person()]

  @Monitor("personList")
  weightChange() {
    console.log(" 检测到数组修改了")
  }

  build() {
    Column() {
      Button("增加一个")
        .onClick(() = > {
          // 1 无效 - 无法检测到数组发生了修改
          this.personList.push(new Person())


          // 2 有效 检测到了数组发生修改
          // const newPerson = [...this.personList, new Person()]
          // this.personList = newPerson
        })
      ForEach(this.personList, (item: Person) = > {
        Text(item.name)
      })
    }
    .width("100%")
    .height("100%")
  }
}

另外可以通过.语法或者监听数组长度来变向实现检测数组元素发生变化

.语法

@ObservedV2
class Person {
  @Trace name: string = "小明"
}


@Entry
@ComponentV2
struct Index {
  @Local
  personList: Person[] = [new Person()]

  @Monitor("personList.0")
  // 如果要单独监听对象中的某个属性  @Monitor("personList.0.name")
  weightChange() {
    console.log(" 检测到数组修改了")
  }

  build() {
    Column() {
      Button("增加一个")
        .onClick(() = > {
          const p = new Person()
          p.name = "小黑"
          this.personList[0] = p
        })
      ForEach(this.personList, (item: Person) = > {
        Text(item.name)
      })
    }
    .width("100%")
    .height("100%")
  }
}

监听数组长度变化

@ObservedV2
class Person {
  @Trace name: string = "小明"
}


@Entry
@ComponentV2
struct Index {
  @Local
  personList: Person[] = [new Person()]

  @Monitor("personList.length")
  weightChange() {
    console.log(" 检测到数组修改了")
  }

  build() {
    Column() {
      Button("增加一个")
        .onClick(() = > {
          const p = new Person()
          p.name = "小黑"
          this.personList.push(p)
        })
      ForEach(this.personList, (item: Person) = > {
        Text(item.name)
      })
    }
    .width("100%")
    .height("100%")
  }
}

@Computed

@Computed为计算属性,可以监听数据变化,从而计算新的值。用法比较简单

@Entry
@ComponentV2
struct Index {
  @Local num: number = 100

  @Computed
  get numText() {
    return this.num * 2
  }

  build() {
    Column() {
      Button("修改")
        .onClick(() = > {
          this.num++
        })
      Text(`原数据 ${this.num}`)
      Text(`计算后 ${this.numText}`)
    }
    .width("100%")
    .height("100%")
  }
}

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • HarmonyOS
    +关注

    关注

    80

    文章

    2157

    浏览量

    36288
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    uM-FPU V2 浮点协处理器:功能特性与应用指南

    uM-FPU V2 浮点协处理器:功能特性与应用指南 引言 在电子设计领域,浮点运算能力对于许多应用至关重要。Micromega Corporation 的 uM-FPU V2 浮点协处理器为
    的头像 发表于 04-11 15:15 471次阅读

    AA Boost Module V2:便捷的电源解决方案

    AA Boost Module V2:便捷的电源解决方案 在电子设计中,电源供应是一个关键问题。今天要给大家介绍的是DFRobot的独家产品——AA Boost Module V2(SKU
    的头像 发表于 03-27 12:50 192次阅读

    如何在 VisionFive v2 上使用外部 GPU?

    如果旧的 amd gpu 在 VisionFive V2 上运行,我想使用带有开源 amd 驱动程序的 amd gpu。我需要什么以及如何将 GPU 连接到 VisionFive v2
    发表于 03-13 06:38

    RDMA设计44:RoCE v2原语功能验证与分析

    它是RoCE v2协议进行信息及数据交换的核心机制,也是DUT需要实现的核心机制之一,对该功能的仿真验证需要考虑指令的提交数据包的组装及发送、数据的DMA处理等。
    的头像 发表于 02-25 09:26 310次阅读
    RDMA设计44:RoCE <b class='flag-5'>v2</b>原语功能验证与分析

    RDMA设计37:RoCE v2 子系统模型设计

    本博文主要交流设计思路,在本博客已给出相关博文160多篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 RoCE v2 子系统模型是用来模拟 RoCE v2 功能
    发表于 02-06 16:19

    RDMA设计30:RoCE v2 发送模块2

    当 RoCE v2 发送模块检测到发送队列非空时,则从发送队列中读取一个发送队列条目,并判断请求类型。根据不同的请求类型和请求长度进入不同的包生成流程,这一过程由请求状态机实现。
    的头像 发表于 01-27 11:56 815次阅读
    RDMA设计30:RoCE <b class='flag-5'>v2</b> 发送模块<b class='flag-5'>2</b>

    RDMA设计29:RoCE v2 发送及接收模块设计2

    本博文主要交流设计思路,在本博客已给出相关博文约100篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 (1)RoCE v2 发送模块 RoCE v2 发送模块
    发表于 01-26 16:47

    RDMA设计28:RoCE v2 发送及接收模块设计

    本博文主要交流设计思路,在本博客已给出相关博文约100篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 RoCE v2 发送及接收模块负责将用户指令组装为 RoCE
    发表于 01-25 10:45

    RDMA设计19:RoCE v2 发送及接收模块设计

    本博文主要交流设计思路,在本博客已给出相关博文约100篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 RoCE v2 发送及接收模块负责将用户指令组装
    发表于 01-06 08:08

    AURIX™ Audio Application Kit for AURIX™ lite Kit V2 深度解析

    AURIX™ Audio Application Kit for AURIX™ lite Kit V2 深度解析 在音频技术不断发展的今天,一款功能强大且灵活的音频应用套件对于电子工程师来说至关重要
    的头像 发表于 12-20 20:35 1448次阅读

    uIO-Stick v2 用户指南:设计、应用与安全要点

    uIO-Stick v2 用户指南:设计、应用与安全要点 在电子工程领域,接口设备对于连接不同系统和实现功能交互起着至关重要的作用。uIO-Stick v2 作为一款用于 MOTIX™ MCU 设备
    的头像 发表于 12-20 11:10 858次阅读

    RDMA设计5:RoCE V2 IP架构

    上面分析,基于RoCE v2 高速数据传输IP 的高速传输应用整体架构如图 1 所示。 图1 基于RoCE V2 IP应用的系统整体架构图 它通过 QSFP28 接口连接上位机进行
    发表于 11-25 10:34

    RDMA over RoCE V2设计1:为什么要设计它?

    基于PC-PC或GPU-GPU之间RDMA设计已有较多厂商投入,虽然有的大厂投入几年后折羽而归,但不影响PC领域成熟应用产品的推广。这里主要讨论在FPGA上设计RDMA over RoCE V2,虽然已有xilinx的ernic应用,但是性价比以及国产化需求还是有其发展空间。
    的头像 发表于 07-15 10:58 816次阅读
    RDMA over RoCE <b class='flag-5'>V2</b>设计1:为什么要设计它?

    第三届大会回顾第6期 | HarmonyOS NEXT原生智能,助力应用低成本生而智能

    原生智能是HarmonyOS NEXT的核心能力之一,通过将人工智能(AI)技术与操作系统深度融合,实现了从底层到应用层的全面智能化。HarmonyOS NEXT的原生智能是如何实现的
    的头像 发表于 07-14 18:04 1316次阅读
    第三届大会回顾第6期 | <b class='flag-5'>HarmonyOS</b> <b class='flag-5'>NEXT</b>原生智能,助力应用低成本生而智能

    第三届大会回顾第2期 | HarmonyOS NEXT内核驱动生态兼容与竞争力思考

    随着HarmonyOS NEXT生态和技术的发展,驱动框架作为北向和南向的生态中枢,有很多的机会。例如,提供更多的信息到应用层,实现精准的性能功耗控制;打破传统的分层解耦,简化关键协议、关键路径等等。
    的头像 发表于 05-19 19:17 1979次阅读
    第三届大会回顾第<b class='flag-5'>2</b>期 | <b class='flag-5'>HarmonyOS</b> <b class='flag-5'>NEXT</b>内核驱动生态兼容与竞争力思考