鸿蒙进阶篇-状态管理之@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;
简单来说,使用步骤就是:
- 将爷组件的状态属性使用@Provide修饰
- 孙组件通过@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、定义与结构 定义:邻接表是图的一种链式存储结构,它通过链表将每个顶点与其相邻的顶点连接起来。 结构: 顶点表:通常使用一个数组来存储图的顶点信息,数组的每个元素对应一个顶点ÿ…...
快速入门web安全
一.确定初衷 1.我真的喜欢搞安全吗? 2.我只是想通过安全赚钱钱吗? 3.我不知道做什么就是随便。 4.一辈子做信息安全吗 这些不想清楚会对你以后的发展很不利,与其盲目的学习web安全,不如先做一个长远的计划。 否则在我看来都是浪费时间。如果你考虑好了…...
rabbitMq两种消费应答失败处理方式
在rabbitMq消费端,有三种应答模式: none:不处理。即消息投递给消费者后立刻 ack 消息会立刻从MQ删除。非常不安全,不建议使用 manual:手动模式。需要自己在业务代码中调用api,发送 ack 或 rejectÿ…...
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中控制色彩? 💯色调纯色调灰色调暗色调 💯…...
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格…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
