HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 八)

news2025/1/10 21:01:47

其他状态管理概述

除了前面章节提到的组件状态管理和应用状态管理,ArkTS还提供了@Watch和$$来为开发者提供更多功能:

  • @Watch用于监听状态变量的变化。
  • $$运算符:给内置组件提供TS变量的引用,使得TS变量和内置组件的内部状态保持同步。

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

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

概述

@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设计的用途是为了快速的计算,异步行为可能会导致重新渲染速度的性能问题。

使用场景

@Watch和自定义组件更新

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

@Component
struct TotalView {
  @Prop @Watch('onCountUpdated') count: number;
  @State total: number = 0;
  // @Watch cb
  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重新渲染。

@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) => {
          Text(`Price: ${item.price.toFixed(2)} €`)
        },
        item => 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组件也重新渲染;重新渲染是异步发生的。

$$语法:内置组件双向同步

$$运算符为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。

内部状态具体指什么取决于组件。例如,bindPopup属性方法的show参数。

使用规则

  • 当前$$支持基础类型变量,以及@State、@Link和@Prop装饰的变量。
  • 当前$$仅支持bindPopup属性方法的show参数,Radio
    组件的checked属性,Refresh
    组件的refreshing参数。
  • $$绑定的变量变化时,会触发UI的同步刷新。

使用示例

以bindPopup属性方法的show参数为例:

// xxx.ets
@Entry
@Component
struct bindPopupPage {
  @State customPopup: boolean = false;

  build() {
    Column() {
      Button('Popup')
        .margin(20)
        .onClick(() => {
          this.customPopup = !this.customPopup
        })
        .bindPopup($$this.customPopup, {
          message: 'showPopup'
        })
    }
  }
}

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

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

相关文章

WSL 安装 NVIDIA显卡驱动

文章目录 WSL 安装 NVIDIA显卡驱动本机显卡信息验证安装 WSL 版 Ubuntu 22.04在 WSL 中安装 NVIDIA显卡驱动WSL 安装 NVIDIA显卡驱动 最近在研究一些 AIGC 工具,由于 Windows 加入了 WSL 之后的各种特性,本文记录一下如何在 WSL 的 Linux发行版 中安装 NVIDIA 显卡驱动的步骤,…

力扣第110题 平衡二叉数 c++ 树 深度优先搜索 二叉树

题目 110. 平衡二叉树 简单 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1: 输入:root [3,9,20,null…

车险计算器微信小程序源码 带流量主功能

车险计算器微信小程序源码带流量主功能,可以精准的算出车险的书目,是一个非常实用的微信小程序源码。 简单的计算让你得知车险价值 另外也支持流量主,具体小编也就不多说了,大家自己搭建研究吧。 源码下载:https://d…

nsoftware Cloud SMS 2022 .NET 22.0.8 Crack

nsoftware Cloud SMS 能够通过各种流行的消息服务(包括 Twilio、Sinch、SMSGlobal、SMS.to、Vonage、Clickatell 等)发送、接收和安排 SMS 消息,从而提供了一种简化且高效的消息服务方法。 Cloud SMS 提供单个 SMS 组件,允许通过…

spring源码解析——IOC之bean创建

正文 在 Spring 中存在着不同的 scope,默认是 singleton ,还有 prototype、request 等等其他的 scope,他们的初始化步骤是怎样的呢?这个答案在这篇博客中给出。 singleton Spring 的 scope 默认为 singleton,第一部…

C++11(左值(引用),右值(引用),移动语义,完美转发)

目录 一、左值与左值引用 1、左值 2、左值引用 3、意义 二、右值与右值引用 1、右值 2、右值引用 三、右值引用使用场景和意义 1、右值的分类 2、移动构造 3、移动赋值 四、万能引用 五、完美转发 一、左值与左值引用 1、左值 左值是一个表示数据的表达式(如变量名…

软件设计之抽象工厂模式

抽象工厂模式指把一个产品变成一个接口,它的子产品作为接口的实现,所以还需要一个总抽象工厂和它的分抽象工厂。 下面我们用一个案例去说明抽象工厂模式。 在class中可以选择super类和medium类,即选择一个产品的子类。在type中可以选择产品的…

LomBok的使用,MyBatis的使用(增删改查)

Lombok是一个Java库&#xff0c;能自动插入编辑器并构建工具&#xff0c;简化Java开发。通过添加注解的方式&#xff0c;不需要 为类编写getter或equels方法&#xff0c;同时可以自动化日志变量。 结构 pom <?xml version"1.0" encoding"UTF-8"?>…

LLM - FastAPI 搭建简易问答 Server

目录 一.引言 二.辅助函数 1.黑名单 2.清除函数 三.模型函数 1.加载模型 2.生成配置 四.服务部署 1.post - predict 2.get - clean_cache 3.main - run_app 五.总结 一.引言 SFT workflow 微调工作流程 一文中我们介绍了模型微调从数据到最终应用的流程 FastAPI …

C语言 选择(分支)

if 语句&#xff08;分支语句/选择语句&#xff09; 结构&#xff1a; if ( expressio ) statement 如果对 expression 求值为真&#xff08;非0&#xff09;&#xff0c;则执行 statement &#xff1b;否则&#xff0c;跳过 statement 。与 while 循环一样&#xff0c…

推荐两款不错的打字练习网站~

前言 对于写论文或者编程工作&#xff0c; 打字是其中十分耗费体力的一环&#xff0c;如果学会了盲打&#xff0c;那么可以起到事倍功半的作用。为了提高工作效率&#xff0c;我特意在网路上搜寻了大量打字练习的网站&#xff0c;最终发现有两款打字网站十分不错&#xff0c;同…

论文阅读-- A simple transmit diversity technique for wireless communications

一种简单的无线通信发射分集技术 论文信息&#xff1a; Alamouti S M. A simple transmit diversity technique for wireless communications[J]. IEEE Journal on selected areas in communications, 1998, 16(8): 1451-1458. 创新性&#xff1a; 提出了一种新的发射分集方…

搭建环境遇到的坑

office2010装完没法激活&#xff0c;因为没有关闭杀毒软件和防火墙。AWTK designer编译时报这个错&#xff0c;scons按这个方法装之后就好了。 装AWTK designer后&#xff0c;打不开软件&#xff0c;总是闪退&#xff0c;装了VS后就打得开了装IAR时找不到ActivationInfo.txt&am…

abp中iquery类使用orderBy接口功能报错问题

在后端写排序时&#xff0c;当使用如下OrderBy(排序字段)时&#xff0c;只引用System.Linq时如下错误&#xff1a; 只是因为缺少一个引用&#xff1a;System.Linq.Dynamic.Core  在如下类文件中引用 System.Linq.Dynamic.Core  注意&#xff1a;切记不能删掉System.Linq的引…

STM32 CubeMX ADC采集(HAL库)

STM32 CubeMX ADC采集&#xff08;HAL库&#xff09; STM32 CubeMX STM32 CubeMX ADC采集&#xff08;HAL库&#xff09;ADC介绍ADC主要特征一、STM32 CubeMX设置二、代码部分三&#xff0c;单通道轮询采样速度总结 ADC介绍 12位ADC是一种逐次逼近型模拟数字转换器。它有多达1…

springboot整合rabbitmq入门(三)

在上一篇文章中介绍了rabbitmq的fanout模式。今天继续学习另一种模式——direct模式。这种模式是rabbitmq的最简单一种模式。 首先创建一个名为helloDirect1的对列 Configuration public class DirectRabbitConfig {Beanpublic Queue directA(){return new Queue("hell…

【翻译】NCLS: Neural Cross-Lingual Summarization

Abstract 跨语言摘要&#xff08;CLS&#xff09;是为不同语言的源文件生成特定语言摘要的任务。现有方法通常将此任务分为两个步骤&#xff1a;摘要和翻译&#xff0c;导致错误传播的问题。为了解决这个问题&#xff0c;我们首次提出了一种端到端的CLS框架&#xff0c;我们称…

淘宝商品销量数据接口,淘宝商品销量数据API接口

淘宝商品销量数据接口是淘宝开放平台提供的一种API接口&#xff0c;通过该接口&#xff0c;商家可以获取到淘宝平台上某一商品的销量数据&#xff0c;包括商品的总销量、近期销量、销售趋势等。 该接口的使用方法是&#xff0c;商家先注册淘宝开放平台账号&#xff0c;申请App…

体会jdk17对于空指针的增强

jdk17 // 可以清楚的看出来a.b.c.num中由于c是空指针&#xff0c;所以导致异常 jdk11 // 只报第6行空指针了&#xff0c;但是因为哪个变量&#xff0c;不知道

打exit_hook,如何找exit_hook的偏移

最近在打比赛的时候&#xff0c;一眼就知道咋做了&#xff0c;打exit_hook为one_gadget 但是泄露出libc之后&#xff0c;没法找到exit_hook的偏移&#xff0c;所以没能拿到一血。搜了好多&#xff0c; 总结大概就是exit_hook不是真实存在的&#xff0c;而是函数指针&#xff0c…