当前位置: 首页 > 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格…...

Offline-First数据同步策略:解决网络中断的智能方案

Offline-First数据同步策略:解决网络中断的智能方案 【免费下载链接】offline-first :electric_plug: Everything you need to know to create offline-first web apps. 项目地址: https://gitcode.com/gh_mirrors/of/offline-first 在当今移动优先的时代&am…...

Synchronized 与 ReentrantLock 深度对比

前言 在Java并发编程中,锁机制是保证线程安全的核心手段。synchronized 和 ReentrantLock 是两种最常用的锁实现,面试中经常被要求对比它们的区别。 本文将深入分析两者的底层原理、功能特性、性能差异以及各自的适用场景。 一、快速概览 维度synchro…...

Meshery 1.0正式发布,为云原生基础设施提供新的管控层

跨多云环境管理Kubernetes基础设施长期以来产生了YAML文件泛滥、配置漂移以及依赖个人而非系统的知识问题。生成基础设施配置的AI工具速度超过了团队审查能力,使这个问题更加难以控制。开源Meshery技术正是为了解决这一问题而构建的。Meshery v1.0现已发布&#xff…...

GPStar Audio串口控制库:嵌入式多轨音频系统开发指南

1. GPStar Audio Serial Library 技术深度解析GPStar Audio Serial Library 是专为 GPStar Technologies 公司推出的 GPStar Audio 与 GPStar Audio XL 系列嵌入式音频播放器设计的串行通信控制库。该库并非通用音频驱动,而是针对特定硬件平台深度定制的、面向实时交…...

如何将TaskWeaver与LangChain无缝集成:扩展AI代理能力边界的终极指南

如何将TaskWeaver与LangChain无缝集成:扩展AI代理能力边界的终极指南 【免费下载链接】TaskWeaver A code-first agent framework for seamlessly planning and executing data analytics tasks. 项目地址: https://gitcode.com/gh_mirrors/ta/TaskWeaver T…...

COA - CNN - BiGRU - Attention分类:新手友好的数据预测方案

COA-CNN-BiGRU-Attention分类 基于浣熊优化算法优化卷积神经网络(CNN)-双向门控循环单元(BGRU)结合注意力机制(Attention)的数据分类预测(可更换为回归/单变量/多变量时序预测,前私),Matlab代码,可直接运行,适合小白新手 无需更改…...

从零构建一个轻量级WebSocket服务器:基于libwebsockets的实战与事件循环剖析

从零构建一个轻量级WebSocket服务器:基于libwebsockets的实战与事件循环剖析 在当今实时应用盛行的时代,WebSocket技术已成为构建即时通讯、实时数据推送等功能的基石。不同于传统的HTTP请求-响应模式,WebSocket提供了全双工通信能力&#xf…...

nli-distilroberta-baseAI应用:心理健康聊天机器人对话逻辑连贯性监测

NLI DistilRoBERTa Base AI应用:心理健康聊天机器人对话逻辑连贯性监测 1. 项目概述 心理健康聊天机器人正成为越来越多人寻求心理支持的重要工具。然而,这类对话系统面临一个关键挑战:如何确保对话内容的逻辑连贯性?这正是nli-…...

Verilog中的strength到底有什么用?一个案例带你理解强弱驱动的实际应用

Verilog中的strength到底有什么用?一个案例带你理解强弱驱动的实际应用 在数字电路设计中,Verilog作为硬件描述语言的标杆,其精确建模能力直接影响仿真结果的可靠性。而strength(强度)这一常被忽视的特性,恰…...

OpenClaw技能开发:为QwQ-32B添加股票数据查询功能

OpenClaw技能开发:为QwQ-32B添加股票数据查询功能 1. 为什么需要开发股票查询技能 去年我在研究量化交易策略时,经常需要手动查询股票数据。每次打开浏览器、登录交易平台、输入代码、导出CSV的重复操作让我疲惫不堪。直到发现OpenClaw可以通过技能扩展…...