当前位置: 首页 > news >正文

鸿蒙进阶篇-状态管理之@Provide与@Consume

大家好,这里是鸿蒙开天组,今天我们来学习一下状态管理中的@Provide与@Consume。

一、概述

嘿!大家还记得这张图吗?不记得也要记得哦,因为这张图里的东西,既是高频必考面试题,也是实际开发中,经常需要用到的玩意,大致上可以这么理解:

下面Components框起来的部分,就是组件之间的状态变量的管理,也就是数据通讯,它会涉及到组件之间的关系,比如父子关系,比如祖孙关系或者其他跨级关系等等。

昨天我们已经学习了左下角的@Prop和@Link,今天需要学的就在中间位置:

 @Provide/@Consume装饰的变量用于跨组件层级(多层组件)同步状态变量。

二、基础使用

先附上官方文档链接:@Provide装饰器和@Consume装饰器

官方文档写的东西比较多,对于新手来说不太容易理解消化和抓住重点,所以我们这里提供了基础结构:

// 写法 1:通过相同的变量名绑定
@Provide a: number = 0;
@Consume a: number;// 写法 2通过相同的变量别名绑定
@Provide b: number = 0;
@Consume('b') c: number;

简单来说,使用步骤就是:

  1. 将爷组件的状态属性使用@Provide修饰
  2. 孙组件通过@Consume修饰

 三、例子说明

这里按步骤一步步来,先给出基础代码模板,大家理解一下其中的结构:

@Entry
@Component// 爷级组件
struct GrandfatherComponent {build() {Column() {Text('爷级组件').fontSize(30).fontWeight(900)ParentComponent()}.padding(10).height('100%').backgroundColor(Color.Gray).width('100%').alignItems(HorizontalAlign.Center).padding({ top: 100 })}
}@Component// 父级组件
struct ParentComponent {// 编写 UIbuild() {Column({ space: 20 }) {Text('我是父级组件').fontSize(22).fontWeight(900)GrandsonComponent()}.backgroundColor(Color.Pink).alignItems(HorizontalAlign.Center).width('90%').margin({ top: 50 }).padding(10).borderRadius(10)}
}@Component// 孙级组件
struct GrandsonComponent {// 编写 UIbuild() {Column({ space: 20 }) {Text('我是孙级组件').fontSize(20).fontWeight(900)}.backgroundColor(Color.Orange).alignItems(HorizontalAlign.Center).width('90%').margin({ top: 50 }).padding(10).borderRadius(10)}
}

界面显示如下:

现在的需求是爷级组件和孙级组件通信传值,问题是,从代码结构上看,中间还隔了一个父级组件。虽然我们也可以基于上一篇讲的@State+@Prop,从爷->父->孙这样实现,但是管理起来毕竟有一个中间商不那么方便,而且这也是华为官方不推荐的做法,因为会消耗额外的性能。所以,我们采用了@Provide+@Consume的方式来实现:

interface Cat {name: stringage: number
}@Entry
@Component// 爷级组件
struct GrandfatherComponent {@Provide cat: Cat = { name: '小花', age: 3 }@Provide food: string = 'fish'build() {Column() {Text('爷级组件').fontSize(30).fontWeight(900)ParentComponent()}.padding(10).height('100%').backgroundColor(Color.Gray).width('100%').alignItems(HorizontalAlign.Center).padding({ top: 100 })}
}@Component// 父级组件
struct ParentComponent {// 编写 UIbuild() {Column({ space: 20 }) {Text('我是父级组件').fontSize(22).fontWeight(900)GrandsonComponent()}.backgroundColor(Color.Pink).alignItems(HorizontalAlign.Center).width('90%').margin({ top: 50 }).padding(10).borderRadius(10)}
}@Component// 孙级组件
struct GrandsonComponent {// 相同变量名@Consume cat: Cat@Consume('food') f: string// 编写 UIbuild() {Column({ space: 20 }) {Text('我是孙级组件').fontSize(20).fontWeight(900)Text(JSON.stringify(this.cat))Text(this.f)Button('修改').onClick(() => {this.cat.name = '小美'this.cat.age = 99this.f += '!'})}.backgroundColor(Color.Orange).alignItems(HorizontalAlign.Center).width('90%').margin({ top: 50 }).padding(10).borderRadius(10)}
}

点击修改效果如下:

 四、补充

1.@Provide+@Consume也是开发中很常用的一对,尤其是组件跨级关系复杂的时候,这个时候就只需要定义一个@Provide在祖级组件中定义,其他多个后代组件@Consume接收即可;

2.在build方法内,当@Provide与@Consume装饰的变量是Object类型、且通过a.b(this.object)形式调用时,b方法内传入的是this.object的原生对象,修改其属性,无法触发UI刷新,尝试思考下以下例子该如何修改,才能触发UI刷新吧(参考答案在官方文档的最后):

class Animal {name:string;type:string;age: number;constructor(name:string, type:string, age:number) {this.name = name;this.type = type;this.age = age;}static changeName1(animal:Animal) {animal.name = 'Black';}static changeAge1(animal:Animal) {animal.age += 1;}
}@Entry
@Component
struct Demo1 {@Provide dog:Animal = new Animal('WangCai', 'dog', 2);changeAge2(animal:Animal) {animal.age += 2;}build() {Column({ space:10 }) {Text(`Demo1: This is a ${this.dog.age}-year-old ${this.dog.type} named ${this.dog.name}.`).fontColor(Color.Red).fontSize(30)Button('changeAge1').onClick(()=>{// 通过静态方法调用,无法触发UI刷新Animal.changeAge1(this.dog);})Button('changeAge2').onClick(()=>{// 使用this通过自定义组件内部方法调用,无法触发UI刷新this.changeAge2(this.dog);})Demo2()}}
}@Component
struct Demo2 {build() {Column({ space:10 }) {Text(`Demo2.`).fontColor(Color.Blue).fontSize(30)Demo3()}}
}@Component
struct Demo3 {@Consume dog:Animal;changeName2(animal:Animal) {animal.name = 'White';}build() {Column({ space:10 }) {Text(`Demo3: This is a ${this.dog.age}-year-old ${this.dog.type} named ${this.dog.name}.`).fontColor(Color.Yellow).fontSize(30)Button('changeName1').onClick(()=>{// 通过静态方法调用,无法触发UI刷新Animal.changeName1(this.dog);})Button('changeName2').onClick(()=>{// 使用this通过自定义组件内部方法调用,无法触发UI刷新this.changeName2(this.dog);})}}
}

好啦,今天的分享就到这里,感谢阅读,你的点赞和收藏都是莫大的支持!

相关文章:

鸿蒙进阶篇-状态管理之@Provide与@Consume

大家好,这里是鸿蒙开天组,今天我们来学习一下状态管理中的Provide与Consume。 一、概述 嘿!大家还记得这张图吗?不记得也要记得哦,因为这张图里的东西,既是高频必考面试题,也是实际开发中&…...

java集合及源码

目录 一.集合框架概述 1.1集合和数组 数组 集合 1.2Java集合框架体系 常用 二. Collection中的常用方法 添加 判断 删除 其它 集合与数组的相互转换 三Iterator(迭代器)接口 3.0源码 3.1作用及格式 3.2原理 3.3注意 3.4获取迭代器(Iterator)对象 3.5. 实现…...

GraphRAG访问模式和知识图谱建模

GraphRAG访问模式和知识图谱建模 GraphRAG访问模式和知识图谱建模什么是GraphRAG了解文本分块检索模式图谱建模相关概念图结构 GraphRAG访问模式和知识图谱建模 graphrag.com是一个开源项目,收集了围绕GraphRAG的相关资源,目前正在快速收集大家的投稿。深…...

TCP/IP协议攻击与防范

一、TCP/IP协议攻击介绍 1.1 Internet的结构​ LAN:局域网 WAN:广域网 WLAN:无线局域网 私有IP地址与公有IP地址? 私有地址:A类:10.0.0.0~10.255.255.255 B类:172.16.0.0~172.31.255.255…...

Java基于 SpringBoot+Vue的口腔管理平台(附源码+lw+部署)

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...

11.26深度学习_神经网络-数据处理

一、深度学习概述 1. 什么是深度学习 ​ 人工智能、机器学习和深度学习之间的关系: ​ 机器学习是实现人工智能的一种途径,深度学习是机器学习的子集,区别如下: ​ 传统机器学习算法依赖人工设计特征、提取特征,而深…...

【人工智能】Python常用库-TensorFlow常用方法教程

TensorFlow 是一个广泛应用的开源深度学习框架,支持多种机器学习任务,如深度学习、神经网络、强化学习等。以下是 TensorFlow 的详细教程,涵盖基础使用方法和示例代码。 1. 安装与导入 安装 TensorFlow: pip install tensorflow…...

微信小程序按字母顺序渲染城市 功能实现详细讲解

在微信小程序功能搭建中,按字母渲染城市会用到多个ES6的方法,如reduce,map,Object.entries(),Object.keys() ,需要组合熟练掌握,才能优雅的处理数据完成渲染。 目录 一、数据分析 二、数据处理 …...

23省赛区块链应用与维护(房屋租凭【下】)

23省赛区块链应用与维护(房屋租凭) 背景描述 随着异地务工人员的增多,房屋租赁成为一个广阔市场。目前,现有技术中的房屋租赁是由房主发布租赁信息,租赁信息发布在房屋中介或租赁软件,租客获取租赁信息后,现场看房,并签订纸质的房屋租赁合同,房屋租赁费用通过中介或…...

数据结构-图-领接表存储

一、了解图的领接表存储 1、定义与结构 定义:邻接表是图的一种链式存储结构,它通过链表将每个顶点与其相邻的顶点连接起来。 结构: 顶点表:通常使用一个数组来存储图的顶点信息,数组的每个元素对应一个顶点&#xff…...

快速入门web安全

一.确定初衷 1.我真的喜欢搞安全吗? 2.我只是想通过安全赚钱钱吗? 3.我不知道做什么就是随便。 4.一辈子做信息安全吗 这些不想清楚会对你以后的发展很不利,与其盲目的学习web安全,不如先做一个长远的计划。 否则在我看来都是浪费时间。如果你考虑好了…...

rabbitMq两种消费应答失败处理方式

在rabbitMq消费端,有三种应答模式: none:不处理。即消息投递给消费者后立刻 ack 消息会立刻从MQ删除。非常不安全,不建议使用 manual:手动模式。需要自己在业务代码中调用api,发送 ack 或 reject&#xff…...

Qt C++(一) 5.12安装+运行第一个项目

安装 1. Download Qt OSS: Get Qt Online Installer 在该链接中下载qt在线安装程序 2. 安装时候,注意关键一步,archive是存档的意思,可以找到旧的版本, 比如5.12 3. 注意组件没必要全选,否则需要安装50个g, 经过请教…...

【RISC-V CPU Debug 专栏 1 -- RISC-V debug 规范】

文章目录 RISC-V Debug调试用例支持的功能限制和不包括的内容RISC-V 调试架构的主要组件用户与调试主机调试翻译器调试传输硬件调试传输模块(DTM)调试模块(DM)调试功能触发模块版本介绍RISC-V Debug RISC-V 调试规范为 RISC-V 处理器提供了一套标准化的调试接口和功能,旨…...

使用Gradle编译前端的项目

使用Gradle编译前端的项目 前言项目结构根项目(parent-project)的 settings.gradle.kts后端项目(backend)的 build.gradle.kts前端项目(frontend)的 build.gradle.kts打包bootJar 前言 最近的项目都是使用…...

网络爬虫——常见问题与调试技巧

在开发网络爬虫的过程中,开发者常常会遇到各种问题,例如网页加载失败、数据提取错误、反爬机制限制等。以下内容将结合实际经验和技术方案,详细介绍解决常见错误的方法,以及如何高效调试和优化爬虫代码。 1. 爬虫过程中常见的错误…...

【AI绘画】Midjourney进阶:色调详解(下)

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 💯前言💯Midjourney中的色彩控制为什么要控制色彩?为什么要在Midjourney中控制色彩? 💯色调纯色调灰色调暗色调 &#x1f4af…...

springboot+redis+lua实现分布式锁

1 分布式锁 Java锁能保证一个JVM进程里多个线程交替使用资源。而分布式锁保证多个JVM进程有序交替使用资源,保证数据的完整性和一致性。 分布式锁要求 互斥。一个资源在某个时刻只能被一个线程访问。避免死锁。避免某个线程异常情况不释放资源,造成死锁…...

【Petri网导论学习笔记】Petri网导论入门学习(十一) —— 3.3 变迁发生序列与Petri网语言

目录 3.3 变迁发生序列与Petri网语言定义 3.4定义 3.5定义 3.6定理 3.5例 3.9定义 3.7例 3.10定理 3.6定理 3.7 有界Petri网泵引理推论 3.5定义 3.9定理 3.8定义 3.10定义 3.11定义 3.12定理 3.93.3 变迁发生序列与Petri网语言 对于 Petri 网进行分析的另一种方法是考察网系统…...

docker-compose文件的简介及使用

Docker Compose是Docker官方的开源项目,主要用于定义和运行多容器Docker应用。以下是对Docker Compose的详细介绍: 一、主要功能: 容器编排:Docker Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML格…...

[护网杯 2018]easy_tornado

这里有一个hint点进去看看,他说md5(cookie_secretmd5(filename)),所以我们需要获得cookie_secret的value 根据题目tornado,它可能是tornado的SSTI 这里吧filehash改为NULL. 是tornado的SSTI 输入{{handler.settings}} (settings 属性是一个字典&am…...

基于STM32的智能风扇控制系统

基于STM32的智能风扇控制系统 持续更新,欢迎关注!!! ** 基于STM32的智能风扇控制系统 ** 近几年,我国电风扇市场发展迅速,产品产出持续扩张,国家产业政策鼓励电风扇产业向高技术产品方向发展,国内企业新增投资项目投…...

决策树——基于乳腺癌数据集与cpu数据集实现

决策树——乳腺癌数据实现 4.1 训练决策树模型,并计算测试集的准确率 1. 读入数据 from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix …...

探索空间自相关:揭示地理数据中的隐藏模式

目录 一、什么是空间自相关? 类型 二、空间自相关的数学基础 空间加权矩阵 三、度量空间自相关的方法 1. 全局自相关 2. 局部自相关 四、空间自相关的实际应用 五、Python实现空间自相关分析 1. 数据准备 2. 计算莫兰指数 3. 局部自相关(LISA 分析&…...

echarts使用示例

柱状图折线图 折柱混合:https://echarts.apache.org/examples/zh/editor.html?cmix-line-bar option {title:{show: true},tooltip: {trigger: axis,axisPointer: {type: cross,crossStyle: {color: #999}}},toolbox: {feature: {dataView: { show: true, readOnl…...

Flink高可用配置(HA)

从Flink架构中我们可以看到,JobManager这个组件非常重要,是中心协调器,负责任务调度和资源管理。默认情况下,每个Flink集群只有一个JobManager实例。这会产生单点故障(SPOF):如果JobManager崩溃,则无法提交新程序,正在运行的程序也会失败。通过JobManager的高可用性,…...

如何编写出色的技术文档

目录 ​编辑 1. 明确文档目的和受众 目的的重要性 了解受众 2. 收集和组织信息 信息收集的技巧 组织信息 3. 规划文档结构 结构规划的重要性 结构规划的步骤 4. 编写内容 语言和风格 内容的组织 编写技巧 5. 审阅和测试 审阅的重要性 测试的必要性 6. 版本控…...

学习日记_20241126_聚类方法(谱聚类Spectral Clustering)

前言 提醒: 文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。 其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展…...

图书系统小案例

目前就实现了分页查询,修改,删除功能 这个小案例练习到了很多技能,比如前后端交互、异步请求、三层架构思想、后端连接数据库、配置文件、基础业务crud等等 感兴趣的小伙伴可以去做一个试试 准备工作 1、使用maven构建一个web工程 打开i…...

目标检测之学习路线(本科版)

以下是为一名计算机科学与技术本科大四学生整理的“目标检测”学习路线,结合了从基础到高级的内容,适合初学者逐步深入。每个阶段都有明确的学习要求、学习建议和资源推荐。 阶段一:基础知识学习 学习要求: 掌握编程语言 Pytho…...

随身办app下载/企业官网seo

(一)针对网站程序,不考虑服务器。 一、查找注入,注意数据库用户权限和站库是否同服。 二、查找XSS,最近盲打很流行,不管怎样我们的目的是进入后台。 三、查找上传,一些能上传的页面,…...

wordpress订阅表格代码/seo公司 上海

linux目录结构及文件基本操作 常用命令 切换目录 cd 当前目录 . 上一级目录 .. (.和..开头的都是隐藏文件) 查看隐藏文件 ls -a 上一级所在目录 - 当前用户home目录 ~ 获取当前所在路径 pwd 创建文件 touch 文件名 创建目录 mkdir 目录名 创建多级目录 m…...

做淘宝需要的网站/谷歌收录查询

el表达式在struts2中使用一般是通过javabean导航来获取数据,一般从web四大域中从小到大的范围中取值,pageContext、request、session、application,这是常用的方式。struts2中对取值方法进行了重写,当四大域没值的时候&#xff0c…...

wordpress首页添加友情/网站推广服务商

原标题:进网许可证、电信设备入网许可证详解!进网许可证也叫入网许可证。入网许可证是加贴在已获得进网许可的电信设备上的质量标志,由信息产业部统一印制和核发,也是行货手机的真品凭证之一。入网许可证上有水印,表面…...

360网站优化/网络推广运营推广

观察es数据目录内会发现大量文件如下图所示: 其中重要的有如下几个,存储三大头: 文件后缀文件含义.fdt文档存储的字段值.fdx文档索引指针,需载入内存.fnm存储fields信息.dvddocValues值.dvmdocValues原信息.doc包含每个term词频…...

网站建设的英语/词爱站的关键词

对象 ① 锁:每条SQL语句 ② 隔离:事务 锁 ① 并发问题 丢失更新 未确认的读取(脏读) 不一致的分析(非重复读):多次读取相同的数据(行)不一致(其他用户…...