【鸿蒙开发】组件状态管理@Prop,@Link,@Provide,@Consume,@Observed,@ObjectLink

1. @Prop 父子单向同步

概述

@Prop装饰的变量和父组件建立单向的同步关系:

  • @Prop变量允许在本地修改,但修改后的变化不会同步回父组件。
  • 当父组件中的数据源更改时,与之相关的@Prop装饰的变量都会自动更新。如果子组件已经在本地修改了@Prop装饰的相关变量值,而在父组件中对应的@State装饰的变量被修改后,子组件本地修改的@Prop装饰的相关变量值将被覆盖。

装饰器使用规则说明

@Prop变量装饰器

说明

装饰器参数

同步类型

单向同步:对父组件状态变量值的修改,将同步给子组件@Prop装饰的变量,子组件@Prop变量的修改不会同步到父组件的状态变量上

允许装饰的变量类型

string、number、boolean、enum类型。

不支持any,不允许使用undefined和null。

必须指定类型。

在父组件中,传递给@Prop装饰的值不能为undefined或者null,反例如下所示。

CompA ({ aProp: undefined })

CompA ({ aProp: null })

@Prop和数据源类型需要相同,有以下三种情况(数据源以@State为例):

  • @Prop装饰的变量和父组件状态变量类型相同,即@Prop : S和@State : S,示例请参考父组件@State到子组件@Prop简单数据类型同步。
  • 当父组件的状态变量为数组时,@Prop装饰的变量和父组件状态变量的数组项类型相同,即@Prop : S和@State : Array<S>,示例请参考父组件@State数组中的项到子组件@Prop简单数据类型同步;
  • 当父组件状态变量为Object或者class时,@Prop装饰的变量和父组件状态变量的属性类型相同,即@Prop : S和@State : { propA: S },示例请参考从父组件中的@State类对象属性到@Prop简单类型的同步。

被装饰变量的初始值

允许本地初始化。

示例

@Entry
@Component
struct Index {@State num: number = 10build() {Column() {Text(`Parent -- ${this.num}`)Button("增加Num的值").onClick(() => {this.num++})Child({ num: this.num })}.width('100%').height('100%')}
}@Component
struct Child {@Prop num: numberbuild() {Column() {Text(`Child -- ${this.num}`)Button("子元素 增加Num的值").onClick(() => {this.num++})}.width('100%').height(100).backgroundColor(Color.Pink)}
}

2. @Link 父子双向同步

概述

@Link装饰的变量与其父组件中的数据源共享相同的值。

装饰器使用规则说明

@Link变量装饰器

说明

装饰器参数

同步类型

双向同步。

父组件中@State, @StorageLink和@Link 和子组件@Link可以建立双向数据同步,反之亦然。

允许装饰的变量类型

Object、class、string、number、boolean、enum类型,以及这些类型的数组。嵌套类型的场景请参考观察变化。

类型必须被指定,且和双向绑定状态变量的类型相同。

不支持any,不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。

说明

不支持Length、ResourceStr、ResourceColor类型,Length、ResourceStr、ResourceColor为简单类型和复杂类型的联合类型。

被装饰变量的初始值

无,禁止本地初始化。

示例

在父组件中传递值时,需要使用 $ 来引用子组件中被 @Link 修饰的数据。

简单类型 string、number、boolean、enum

@Entry
@Component
struct Index {@State num: number = 10build() {Column() {Text(`${this.num}`)Button("增加Num的值").onClick(() => {this.num++})Child({ num: $num })}.width('100%').height('100%')}
}@Component
struct Child {@Link num: numberbuild() {Column() {Text(`${this.num}`)Button("子元素 增加Num的值").onClick(() => {this.num++})}.width('100%').height(100).backgroundColor(Color.Pink)}
}

复杂类型 Object、class

class Person {name: string = ""age: number = 0constructor(name: string, age: number) {this.name = name;this.age = age;}
}@Entry
@Component
struct Index {@State p: Person = { name: "lili", age: 18 }build() {Column() {Text(`${this.p.name}--${this.p.age}`)Button("增加age的值").onClick(() => {this.p.age++})Child({ p: $p })}.width('100%').height('100%')}
}@Component
struct Child {@Link p: Personbuild() {Column() {Text(`${this.p.name}--${this.p.age}`)Button("子元素 增加age的值").onClick(() => {this.p.age++})}.width('100%').height(100).backgroundColor(Color.Pink)}
}

3. @Provide / @Consume 后代组件双向同步

概述

@Provide/@Consume装饰的状态变量有以下特性:

  • @Provide装饰的状态变量自动对其所有后代组件可用,即该变量被“provide”给他的后代组件。由此可见,@Provide的方便之处在于,开发者不需要多次在组件之间传递变量。
  • 后代通过使用@Consume去获取@Provide提供的变量,建立在@Provide和@Consume之间的双向数据同步,与@State/@Link不同的是,前者可以在多层级的父子组件之间传递。
  • @Provide和@Consume可以通过相同的变量名或者相同的变量别名绑定,变量类型必须相同。
// 通过相同的变量名绑定
@Provide a: number = 0;
@Consume a: number;// 通过相同的变量别名绑定
@Provide('a') b: number = 0;
@Consume('a') c: number;

@Provide和@Consume通过相同的变量名或者相同的变量别名绑定时,@Provide修饰的变量和@Consume修饰的变量是一对多的关系。不允许在同一个自定义组件内,包括其子组件中声明多个同名或者同别名的@Provide装饰的变量。

装饰器使用规则说明

@State的规则同样适用于@Provide,差异为@Provide还作为多层后代的同步源。

@Provide变量装饰器

说明

装饰器参数

别名:常量字符串,可选。

如果指定了别名,则通过别名来绑定变量;如果未指定别名,则通过变量名绑定变量。

同步类型

双向同步。

从@Provide变量到所有@Consume变量以及相反的方向的数据同步。双向同步的操作与@State和@Link的组合相同。

允许装饰的变量类型

Object、class、string、number、boolean、enum类型,以及这些类型的数组。嵌套类型的场景请参考观察变化。

不支持any,不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。

必须指定类型。@Provide变量的@Consume变量的类型必须相同。

说明

不支持Length、ResourceStr、ResourceColor类型,Length、ResourceStr、ResourceColor为简单类型和复杂类型的联合类型。

被装饰变量的初始值

必须指定。

@Consume变量装饰器

说明

装饰器参数

别名:常量字符串,可选。

如果提供了别名,则必须有@Provide的变量和其有相同的别名才可以匹配成功;否则,则需要变量名相同才能匹配成功。

同步类型

双向:从@Provide变量(具体请参见@Provide)到所有@Consume变量,以及相反的方向。双向同步操作与@State和@Link的组合相同。

允许装饰的变量类型

Object、class、string、number、boolean、enum类型,以及这些类型的数组。嵌套类型的场景请参考观察变化。

不支持any,不允许使用undefined和null。

必须指定类型。@Provide变量的@Consume变量的类型必须相同。

说明

  • @Consume装饰的变量,在其父节点或者祖先节点上,必须有对应的属性和别名的@Provide装饰的变量。

被装饰变量的初始值

无,禁止本地初始化。

示例

class Person {name: string = ""age: number = 0constructor(name: string, age: number) {this.name = name;this.age = age;}
}@Entry
@Component
struct Index {@Provide p: Person = { name: "lili", age: 18 }build() {Column() {Text(`祖先`)Text(`${this.p.name}--${this.p.age}`)Button("增加age的值").onClick(() => {this.p.age++})Parent()}.width('100%').height('100%')}
}@Component
struct Parent {build() {Column() {Text(`父级`)Child()}.width('100%').height(300).backgroundColor(Color.Pink)}
}@Component
struct Child {@Consume p: Personbuild() {Column() {Text(`后代`)Text(`${this.p.name}--${this.p.age}`)Button("子元素 增加age的值").onClick(() => {this.p.age++})}.width('100%').height(200).backgroundColor(Color.Orange)}
}

4. @Observed / @ObjectLink 嵌套类对象属性变化

概述

@ObjectLink和@Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步:

  • 被@Observed装饰的类,可以被观察到属性的变化;
  • 子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class object中的属性,这个属性同样也需要被@Observed装饰。
  • 单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。

装饰器使用规则说明

@Observed类装饰器

说明

装饰器参数

类装饰器

装饰class。需要放在class的定义前,使用new创建类对象。

@ObjectLink变量装饰器

说明

装饰器参数

同步类型

不与父组件中的任何类型同步变量。

允许装饰的变量类型

必须为被@Observed装饰的class实例,必须指定类型。

不支持简单类型,可以使用@Prop。

@ObjectLink的属性是可以改变的,但是变量的分配是不允许的,也就是说这个装饰器装饰变量是只读的,不能被改变。

被装饰变量的初始值

不允许。

示例

@Observed
class BookItem {id: number = 0name: string = ""size: number = 0constructor(id: number, name: string, size: number) {this.id = idthis.name = namethis.size = size}
}@Entry
@Component
struct Index {@State bookArr: BookItem[] = [new BookItem(1, "Java", 10),new BookItem(2, "ArkTS", 20)]build() {Column({ space: 10 }) {Text(`${JSON.stringify(this.bookArr)}`)Text(`${JSON.stringify(this.bookArr[0].size)}`)//注意:子组件页面数据是更新的,父组件页面数据未更新//原因:数据本身是更新的,父组件页面不在重新渲染,子组件页面重新渲染Button("修改Size").onClick(() => {this.bookArr[0].size += 1//修改数据的方法1 重新赋值 解构赋值和展开运算 (Next不能用了)//this.bookArr[0] = { ...this.bookArr[0], size:30 }//修改数据的方法2 重新赋值// const book = this.bookArr[0]// this.bookArr[0] = new BookItem(book.id, book.name, 30)})ForEach(this.bookArr,(item) => {Child({ item })},(item) => JSON.stringify(item))}.width('100%').height('100%')}
}@Component
struct Child {@ObjectLink item: BookItembuild() {Column() {Text(`${JSON.stringify(this.item)}`)Text(`${JSON.stringify(this.item.size)}`)Button("子元素---修改Size").onClick(() => {this.item.size += 1})}.width('100%').height('100').backgroundColor(Color.Pink)}
}

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

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

相关文章

【数据结构练习题】队——1.用队实现栈2.用栈实现队

♥♥♥♥♥个人主页♥♥♥♥♥ ♥♥♥♥♥数据结构练习题总结专栏♥♥♥♥♥ ♥♥♥♥♥上一章&#xff1a;堆的练习题♥♥♥♥♥ 文章目录 1.用队去实现栈1.1问题描述1.2思路分析1.3绘图分析1.4代码实现2.用栈实现队2.1问题描述2.2思路分析1.3绘图分析2.4代码实现 1.用队去实现…

FreeRTOS学习 -- 再识

工作中一直使用FreeRTOS进行着开发&#xff0c;但是没有进行过系统的总结过。现在将快速使用几天时间将FreeRTOS相关知识点加以总结。 官网&#xff1a; https://www.freertos.org/zh-cn-cmn-s/ 参看资料&#xff1a; 正点原子 STM32F1 FreeRTOS开发手册_V1.2.pdf The FreeRTOS…

Linux CPU利用率

Linux CPU利用率 在线上服务器观察线上服务运行状态的时候&#xff0c;绝大多数人都是喜欢先用 top 命令看看当前系统的整体 cpu 利用率。例如&#xff0c;随手拿来的一台机器&#xff0c;top 命令显示的利用率信息如下 这个输出结果说简单也简单&#xff0c;说复杂也不是那么…

使用Mac自带终端进行远程ssh连接Linux服务器

废话不多说&#xff0c;直接上图 好吧&#xff0c;我承认我是多此一举&#xff0c;脱裤子放pi了&#xff0c;其实只需要在终端输入一行命令就可以了&#xff08;呜呜&#xff5e;&#xff09; ssh rootip -p 22 需要注意的是&#xff0c;命令里的ip地址同样要替换成你自己的服…

前端工程化理解 (2024 面试题)

最好介绍远古世界最好随性一点&#xff0c;不要太刻板 &#xff0c;不然像背书 什么是前端工程化&#xff1f; - 知乎 前端工程化的历史 互联网初期&#xff0c;09 年以前&#xff0c;页面只需要展示一些列表、表格、文章内容以及简单图片即可&#xff0c;其目的是为了传送信…

SpringCloudAlibaba

文章目录 一、SpringCloudAlibaba是什么&#xff1f;二、核心组件1 Nacos1.1 Nacos介绍1.2 什么是Nacos&#xff1f;1.3 为何使用Nacos&#xff1f; 2.Sentinel2.1 什么是Sentinel2.2 Sentinel好处 3 GateWay3.1 网关介绍3.2 GateWay3.3 基本概念&#xff1a; 4 Seata4.1 分布式…

4.进程相关

1.关于进程和程序的相关定义 1.1 程序的相关定义 程序通俗来讲就是我们的源代码文件&#xff0c;然后里面还包含了其他的文件信息 程序入口地址&#xff1a;也就是 main 函数的位置 1.2 进程的相关定义 进程需要资源&#xff1a;CPU &#xff0c;内存 进程是一个抽象定义&a…

免费游戏云服务器推荐,一键搭建我的世界(MC)及幻兽帕鲁服务器!

随着云计算的普及和发展&#xff0c;越来越多的人开始尝试在云服务器上搭建游戏服务器。本文将为大家推荐一款免费游戏云服务器&#xff0c;可以一键搭建我的世界(MC)或者幻兽帕鲁服务器。 雨云是一家国内的云计算服务提供商&#xff0c;为了吸引用户&#xff0c;推出了积分免费…

从误差分解看Few-shot的核心问题

FSL训练过程一般都是最小化经验误差ERM。 同时&#xff0c;由于现实任务的实际数据分布 是未知的&#xff0c;因此无法找到一个最优的参数组合 &#xff0c;能最小化期望损失&#xff08;最小值多少也是未知的&#xff09;&#xff0c;我们能做的实际上是尽可能的去找一个参数…

redis string底层为什么使用sds, sds好处?redis 的动态字符串优点?

1. redis 的键值对&#xff0c;都是由对象组成的&#xff0c; 其中键总是一个字符串对象&#xff08;string object&#xff09; 而键的value则可以是&#xff1a;“字符串对象”&#xff0c; “列表对象 &#xff08;list object&#xff09;”&#xff0c;“哈希对象 (hash o…

蓝桥杯每日一题(背包dp,线性dp)

//3382 整数拆分 将 1,2,4,8看成一个一个的物品&#xff0c;以完全背包的形式放入。 一维形式&#xff1a;f]0]1; #include<bits/stdc.h> using namespace std; //3382整数拆分 const int N1e610, M5e510; int mod1e9; int f[N],n; int main() {cin>>n;//转化为完…

linux 迁移home目录以及修改conda中pip的目录,修改pip安装路径

1&#xff09;sudo rsync -av /home/lrf /data/home/lrf 将/home目录下的文件进行复制&#xff08;假设机械硬盘挂载在/data目录下&#xff09;** 2&#xff09;usermod -d /data/home/lrf -m lrf 修改用户$HOME变量** 3&#xff09;vi /etc/passwd 查看对应用户的$HOME变量是…

网络安全加密算法---对称加密

三位同学一组完成数据的对称加密传输。 三位同学分别扮演图中 A、B 和 KDC 三个角色&#xff0c;说明 KA、KB&#xff0c;KAB 和发送的数据Data 的内容。 给出图中 2 和 3 中的数据&#xff0c;以及 Data 加密后的密文。可以完成多轮角色互换的通信 过程。其中一轮过程要求 K…

洗地机如何选?入手这四款优质好有,幸福感爆棚!

家庭清洁作为每天都必干的一件事&#xff0c;房屋的整洁是让人保持心情愉悦的一种方式。不过每次拿着清洁工具一顿劳作后总是会腰酸背痛&#xff0c;但是洗地机的出现为我们解放了双手。相对于传统的清洁工具&#xff0c;洗地机功能更多样更高效。那么市面上洗地机哪个牌子好&a…

LeetCode31. 下一个排列(Java)

题目&#xff1a; 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列…

PyQt PySide6零基础入门与项目实战视频教程

目录 课程亮点课程大纲第一章&#xff1a;基础篇 PySide6开发环境安装第二章 控件与布局篇 PySide6常用控件与界面布局使用介绍第三章 信号槽与事件机制第四章 QMainWindow应用篇第五章 样式表qss与自定义控件第六章 图表与曲线第七章 数据库编程第八章 项目实战&#xff1a;高…

Java—抽象方法与接口

声明&#xff1a;以下内容是根据B站黑马程序员的Java课程&#xff0b;博主自己的理解整理而成&#xff0c;课程很好&#xff0c;适合初学者学习。 关于此类题目&#xff0c;重要的是识别出用什么来实现&#xff0c;到底是接口还是抽象方法&#xff0c;还是共有的属性等等&…

QT:事件机制

作业&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include<QPushButton> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAME…

Vue3---基础1(认识,创建)

变化 相对于Vue2&#xff0c;Vue3的变化&#xff1a; 性能的提升 打包大小减少 41% 初次渲染快 55%&#xff0c;更新渲染快133% 内存减少54% 源码的升级 使用 proxy 代替 defineProperty 实现响应式 重写虚拟 DOM 的实现和 Tree-shaking TypeScript Vue3就可以更好的支持TypeSc…

Redis中的集群(四)

集群 槽指派 CLUSTER ADDSLOTS命令的实现 CLUSTER ADDSLOTS命令接受一个或多个槽作为参数&#xff0c;并将所有输入的槽指派给接收该命令的节点负责: CLUSTER ADDSLOTS <slot> [slot ...]CLUSTER ADDSLOTS命令的实现可以用以下伪代码来表示: def CLUSTER_ADDSLOTS(*…