HarmonyOS:@Watch装饰器:状态变量更改通知

@Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数。

说明
从API version 9开始,该装饰器支持在ArkTS卡片中使用。
从API version 11开始,该装饰器支持在元服务中使用。

一、概述

@Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法将被调用。@Watch在ArkUI框架内部判断数值有无更新使用的是严格相等(===),遵循严格相等规范。当在严格相等为false的情况下,就会触发@Watch的回调。

二、装饰器说明

@Watch补充变量装饰器说明
装饰器参数必填。常量字符串,字符串需要有引号。是(string) => void自定义成员函数的方法的引用。
可装饰的自定义组件变量可监听所有装饰器装饰的状态变量。不允许监听常规变量。
装饰器的顺序建议@State、@Prop、@Link等装饰器在@Watch装饰器之前。

三、语法说明

类型说明
(changedPropertyName? : string) => void该函数是自定义组件的成员函数,changedPropertyName是被watch的属性名。
在多个状态变量绑定同一个@Watch的回调方法的时候可以通过changedPropertyName进行不同的逻辑处理。
将属性名作为字符串输入参数,不返回任何内容。

四、观察变化和行为表现

  1. 当观察到状态变量的变化(包括双向绑定的AppStorage和LocalStorage中对应的key发生的变化)的时候,对应的@Watch的回调方法将被触发;
  2. @Watch方法在自定义组件的属性变更之后同步执行;
  3. 如果在@Watch的方法里改变了其他的状态变量,也会引起状态变更和@Watch的执行;
  4. 在第一次初始化的时候,@Watch装饰的方法不会被调用,即认为初始化不是状态变量的改变。只有在后续状态改变时,才会调用@Watch回调方法。

五、限制条件

  • 建议开发者避免无限循环。循环可能是因为在@Watch的回调方法里直接或者间接地修改了同一个状态变量引起的。为了避免循环的产生,建议不要在@Watch的回调方法里修改当前装饰的状态变量;
  • 开发者应关注性能,属性值更新函数会延迟组件的重新渲染(具体请见上面的行为表现),因此,回调函数应仅执行快速运算;
  • 不建议在@Watch函数中调用async await,因为@Watch设计的用途是为了快速的计算,异步行为可能会导致重新渲染速度的性能问题。

六、使用场景

6.1 @Watch和自定义组件更新

以下示例展示组件更新和@Watch的处理步骤。count在CountModifier中由@State装饰,在TotalView中由@Prop装饰。

@Component
struct TotalView {@Prop @Watch('onCountUpdated') count: number = 0;@State total: number = 0;// @Watch 回调onCountUpdated(propName: string): void {this.total += this.count;}build() {Text(`Total: ${this.total}`)}
}@Entry
@Component
struct CountModifier {@State count: number = 0;build() {Column() {Button('add to basket').onClick(() => {this.count++})TotalView({ count: this.count })}}
}

处理步骤:

  1. CountModifier自定义组件的Button.onClick点击事件自增count。
  2. 由于@State count变量更改,子组件TotalView中的@Prop被更新,其@Watch(‘onCountUpdated’)方法被调用,更新了子组件TotalView 中的total变量。
  3. 子组件TotalView中的Text重新渲染。

运行效果图
在这里插入图片描述

6.2 @Watch与@Link组合使用

以下示例说明了如何在子组件中观察@Link变量。

class PurchaseItem {static NextId: number = 0;public id: number;public price: number;constructor(price: number) {this.id = PurchaseItem.NextId++;this.price = price;}
}@Component
struct BasketViewer {@Link @Watch('onBasketUpdated') shopBasket: PurchaseItem[];@State totalPurchase: number = 0;updateTotal(): number {let total = this.shopBasket.reduce((sum, i) => sum + i.price, 0);// 超过100欧元可享受折扣if (total >= 100) {total = 0.9 * total;}return total;}// @Watch 回调onBasketUpdated(propName: string): void {this.totalPurchase = this.updateTotal();}build() {Column() {ForEach(this.shopBasket,(item: PurchaseItem) => {Text(`Price: ${item.price.toFixed(2)} €`)},(item: PurchaseItem) => item.id.toString())Text(`Total: ${this.totalPurchase.toFixed(2)} €`)}}
}@Entry
@Component
struct BasketModifier {@State shopBasket: PurchaseItem[] = [];build() {Column() {Button('Add to basket').onClick(() => {this.shopBasket.push(new PurchaseItem(Math.round(100 * Math.random())))})BasketViewer({ shopBasket: $shopBasket })}}
}

处理步骤如下:

  1. BasketModifier组件的Button.onClick向BasketModifier shopBasket中添加条目;
  2. @Link装饰的BasketViewer shopBasket值发生变化;
  3. 状态管理框架调用@Watch函数BasketViewer onBasketUpdated 更新BasketViewer TotalPurchase的值;
  4. @Link shopBasket的改变,新增了数组项,ForEach组件会执行item Builder,渲染构建新的Item项;@State totalPurchase改变,对应的Text组件也重新渲染;重新渲染是异步发生的。

运行效果图
在这里插入图片描述

6.3 使用changedPropertyName进行不同的逻辑处理

以下示例说明了如何在@Watch函数中使用changedPropertyName进行不同的逻辑处理。

@Entry
@Component
struct UsePropertyName {@State @Watch('countUpdated') apple: number = 0;@State @Watch('countUpdated') cabbage: number = 0;@State fruit: number = 0;// @Watch 回调countUpdated(propName: string): void {if (propName == 'apple') {this.fruit = this.apple;}}build() {Column() {Text(`Number of apples: ${this.apple.toString()}`).fontSize(20).margin({ top: 16 })Text(`Number of cabbages: ${this.cabbage.toString()}`).fontSize(20).margin({ top: 16 })Text(`Total number of fruits: ${this.fruit.toString()}`).fontSize(20).margin({ top: 16 })Button('Add apples').margin({ top: 16 }).onClick(() => {this.apple++;})Button('Add cabbages').margin({ top: 16 }).onClick(() => {this.cabbage++;})}}
}

处理步骤如下:

  1. 点击Button(‘Add apples’)时,apple的值发生变化。
  2. 状态管理框架调用@Watch函数countUpdated,发生变化的状态变量名为apple,满足if逻辑条件,fruit的值被改变;
  3. 绑定了apple,fruit状态变量的Text重新渲染。
  4. 点击Button(‘Add cabbages’)时,cabbage的值发生变化。
  5. 状态管理框架调用@Watch函数countUpdated,发生变化的状态变量名为cabbage,不满足if逻辑条件,fruit的值不发生变化;
  6. 绑定了cabbage状态变量的Text重新渲染。

效果图1
在这里插入图片描述

效果图2
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/57319.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL PRIMARY KEY

SQL PRIMARY KEY 概述 在关系型数据库中,主键(PRIMARY KEY)是一个非常重要的概念。它是表中每一行数据的唯一标识符,用于保证数据的完整性和准确性。本文将详细介绍SQL中的主键,包括其定义、作用、如何创建和修改主键…

模版标签示例

通用数据 {$website_dictionary.CONTACT_PHONE} {$website_dictionary.CONTACT_TEL} {$website_dictionary.CONTACT_400} {$website_dictionary.CONTACT_EMAIL} {$website_dictionary.CONTACT_ADDRESS}头部菜单 header.html {notempty name"menu"}<!-- 一级 --&…

【Qt】控件——布局管理器、常见的布局管理器、布局管理器的使用、垂直布局、水平布局、网格布局、表单布局、Spacer

文章目录 Qt布局管理器垂直布局水平布局网格布局表单布局Spacer Qt 布局管理器 之前在使用 Qt 创建界面上的控件时&#xff0c;大多是通过 “绝对定位” 的方式来设定的。即每个控件所在的位置都需要计算坐标&#xff0c;最终通过 setGeometry 或者 move 方式进行摆放。 然而&a…

配置和排查 Lombok 在 IDEA 中使用的详细步骤

在日常开发中&#xff0c;Java 代码常常需要大量的样板代码&#xff0c;比如 getter、setter、toString 等方法。Lombok 是一个 Java 库&#xff0c;可以通过注解的方式&#xff0c;自动生成这些常见的代码&#xff0c;从而让代码更加简洁、清晰。比如&#xff0c;我们可以通过…

【牛客算法】某司面试算法题:设计LRU缓存结构

一、算法题描述 1.1 算法描述 设计LRU(最近最少使用)缓存结构&#xff0c;该结构在构造时确定大小&#xff0c;假设大小为 capacity &#xff0c;操作次数是 n &#xff0c;并有如下功能: Solution(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存get(key)&#x…

Java面试题集锦

1. 计算机网络 1、什么是计算机网络 2、什么是协议 3、什么是IP地址 4、什么是子网 5、什么是DNS 6、什么是NAT 7、什么是带宽和延迟 8、什么是VPN 9、路由器和交换机的区别 10、OSI与TCP/IP模型 11、TCP与UDP的区别 12、TCP三次握手四次挥手 13、HTTP和HTTPS的区…

快速在win11上利用hyper-v安装虚拟系统:遭遇Start PXE over ipv4

以前习惯使用VMware&#xff0c;但在win11上折腾了很久都遇到各种麻烦&#xff0c;索性就上微软自家的Hyper-V&#xff0c;。作为微软自家的产品&#xff0c;Hyper-V 与 Windows 11 操作系统紧密结合&#xff0c;具有良好的兼容性和稳定性。在安装和使用过程中&#xff0c;与系…

Python中的数据可视化:Matplotlib基础与高级技巧

Python中的数据可视化&#xff1a;Matplotlib基础与高级技巧 数据可视化是数据分析和数据科学中不可或缺的一部分。通过图表&#xff0c;我们可以更直观地观察数据的分布和趋势。Matplotlib作为Python最基础、也是最广泛使用的绘图库之一&#xff0c;不仅支持多种常用图表&…

沈阳乐晟睿浩科技有限公司抖音小店新篇章

在当今数字化时代&#xff0c;电商行业如雨后春笋般迅速崛起&#xff0c;其中抖音小店凭借其庞大的用户基础、精准的推荐算法和便捷的购物体验&#xff0c;成为了电商领域的新宠。在这场电商变革中&#xff0c;沈阳乐晟睿浩科技有限公司&#xff08;以下简称“乐晟睿浩”&#…

正则表达式:强大的文本匹配与处理工具

正则表达式&#xff1a;强大的文本匹配与处理工具 正则表达式&#xff08;Regular Expression&#xff0c;简称 regex&#xff09;是一种用于定义搜索模式的字符串&#xff0c;用于匹配和处理文本。它广泛应用于数据清洗、文本分析、日志分析等场景。本文将介绍正则表达式的基…

1,国产FPGA(紫光同创)-IP核-PLL

本文默认在0&#xff0c;国产FPGA&#xff08;紫光同创&#xff09;-新建PDS工程基础上完成。 1&#xff0c;添加IP核 右击&#xff08;1&#xff09;空白处进行添加&#xff0c;点击New IP&#xff08;2&#xff09;进行新建IP核。 选择本次实验要配置的IP核-PLL&#xff08;…

“智能二维码”实现光伏行业数字信息化管理

近日&#xff0c;为了提升管理效率&#xff0c;国电投建业光伏电站将二维码引入设备巡视和班组建设中。 首先&#xff0c;使用传统纸质巡视作业卡&#xff0c;巡视工作强度大&#xff0c;容易出现错误&#xff1b;此外&#xff0c;“三会一活动”和培训记录等班组建设过程材料大…

linux之awk

awk 是一个强大的文本处理工具&#xff0c;广泛用于Linux和Unix系统中。它可以用来处理和分析文本文件&#xff0c;尤其是那些以固定格式排列的数据。下面是一些简单的 awk 用法示例&#xff0c;帮助你更好地理解它的基本功能。 1. 打印文件的特定列 假设有一个CSV文件 data.…

电脑录屏不用愁!四款免费录屏软件深度体验分享

虽然我不是专业的&#xff0c;但是我有一颗想要变得专业的心。作为一名经常需要录制教学视频和游戏直播的博主&#xff0c;我深知一款好用的录屏软件对于工作效率的重要性。今天&#xff0c;我就来和大家分享一下我最近亲测的四款免费录屏软件&#xff0c;来看看哪一款更适合你…

shodan5,参数使用,批量查找Mongodb未授权登录,jenkins批量挖掘

查找美国安全局漏洞 nww.nsa.gov&#xff08;美国安全局官方网站) net参数使用 搜索指定的ip网段 shodan search --limit 10 --fields ip_str,port net:208.88.84.0/24 (老美国家安全局的一个网段)可能直接访问不太行&#xff0c;可以使用host参数&#xff0c;得到域名再去…

部署MiniCPM-V

GitHub - OpenBMB/MiniCPM-V: MiniCPM-V 2.6: A GPT-4V Level MLLM for Single Image, Multi Image and Video on Your Phone 安装和执行 "Local WebUI Demo" 的步骤如下&#xff1a; 克隆仓库并导航到源文件夹&#xff1a; git clone https://github.com/OpenBMB/M…

Vue 权限管理

vue 中&#xff0c;比较常见的需要进行权限管控的权限控制实现思路有四条&#xff1a;、 菜单的控制 在登录请求中&#xff0c;会得到权限数据&#xff0c;当然&#xff0c;这个需要后端返回数据的支持&#xff0c;前端根据权限数据&#xff0c;展示对应的菜单&#xff0c;单…

MongoDB 8.0.3版本安装教程

MongoDB 8.0.3版本安装教程 一、下载安装 1.进入官网 2.选择社区版 3.点击下载 4.下载完成后点击安装 5.同意协议&#xff0c;下一步 6.选择第二个Custon&#xff0c;自定义安装 7.选择安装路径 &#xff01;记住安装路径 8.默认&#xff0c;下一步 9.取…

用于约束多目标优化的新型双阶段双种群进化算法

PPT链接&#xff1a;人工智能论文课程汇报介绍PPT资源-CSDN文库 A Novel Dual-Stage Dual-Population Evolutionary Algorithm for Constrained Multi-Objective Optimization IEEE Transactions on Evolutionary Computation, Volume 26, Issue 5, Pages 1129-1143, October …

C语言中的位操作

第一章 变量某位赋值与连续赋值 寄存器 | 值 //例如&#xff1a;a 1000 0011b a | (1<<2) //a 1000 0111 b 单独赋值 a | (3<<2*2) // 1011 0011b 连续赋值 第二章 变量某位清零与连续清零 寄存器 & ~&#xff08;&#xff09; 值 //例子&#xff1a;a …