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

鸿蒙原生开发手记:徒步迹 - @Provide/@Consume 跨组件通信

掌握跨级组件通信,构建灵活可复用的组件体系


一、前言

在复杂应用中,经常出现祖先组件需要向后代组件传递数据的场景。如果逐层通过 @Prop 传递,会导致"属性逐层传递"的问题(prop drilling),代码冗长且难以维护。

ArkUI 提供了 @Provide/@Consume 装饰器对,实现跨级组件通信,无需中间组件参与。


二、@Provide/@Consume 原理

2.1 基本概念

@Provide 祖先组件 │ │ (自动传递) │ v @Consume 后代组件 1 @Consume 后代组件 2
  • @Provide:在祖先组件中定义,提供数据
  • @Consume:在后代组件中声明,自动获取祖先的 Provide 数据

2.2 基础用法

// 祖先组件 - 提供数据@Componentstruct AppRoot{@Provide('isLoggedIn')isLoggedIn:boolean=false;@Provide('userName')userName:string='';build(){Column(){// 中间组件(不需要传递任何数据)MainContent();}}}// 中间组件 - 不接触数据@Componentstruct MainContent{build(){Column(){UserProfile();}}}// 后代组件 - 消费数据@Componentstruct UserProfile{@Consume('isLoggedIn')isLoggedIn:boolean;@Consume('userName')userName:string;build(){Column(){if(this.isLoggedIn){Text(`欢迎,${this.userName}`).fontSize(18);}else{Button('登录');}}}}

2.3 类型推断(省略别名)

当不指定别名时,@Provide/@Consume 使用变量名自动匹配:

@Componentstruct Ancestor{@ProvidestepCount:number=0;// 变量名作为标识build(){Descendant();}}@Componentstruct Descendant{@ConsumestepCount:number;// 自动匹配同名变量// 等价于 @Consume('stepCount') stepCount: number;build(){Text(`步数:${this.stepCount}`);}}

三、@Provide/@Consume vs @Prop/@Link

特性@Prop/@Link@Provide/@Consume
传递层级父子之间任意层级
中间组件需要逐层传递无需参与
使用场景直接父子跨级祖先→后代
性能较好稍差(需查找)
可读性显式传递隐式传递

选择建议

  • 父子组件:用 @State/@Prop/@Link
  • 跨 2 层以上:用 @Provide/@Consume
  • 全局状态:用 AppStorage

四、实战:徒步迹全局登录状态

在徒步迹 App 中,登录状态需要在多个页面间共享:

// AppRoot - 应用根组件@Entry@Componentstruct AppRoot{@Provide('isLogged')isLogged:boolean=false;@Provide('currentUser')currentUser:User|null=null;@Provide('themeMode')themeMode:string='light';build(){Column(){if(!this.isLogged){LoginPage();}else{MainTabPage();}}.width('100%').height('100%');}}

4.1 登录页面使用

@Componentstruct LoginPage{@Consume('isLogged')isLogged:boolean;@Consume('currentUser')currentUser:User|null;build(){Column(){Button('登录').onClick(()=>{// 成功后更新全局状态this.isLogged=true;this.currentUser={id:1,nickname:'徒步爱好者',avatar:'',phone:'138****0000',};});}}}

4.2 个人中心页面使用

@Componentstruct ProfilePage{@Consume('isLogged')isLogged:boolean;@Consume('currentUser')currentUser:User|null;build(){Column(){if(this.currentUser){Text(this.currentUser.nickname).fontSize(20).fontWeight(FontWeight.Bold);Text(`手机:${this.currentUser.phone}`).fontSize(14).fontColor('#666');}Button('退出登录').onClick(()=>{this.isLogged=false;this.currentUser=null;});}}}

五、多个 Provide/Consume 的协作

// 追踪页 - 提供多个状态@Componentstruct TrackingSection{@Provide('status')status:string='idle';@Provide('trackData')trackData:TrackData={duration:0,distance:0,points:[],};build(){Column(){ControlPanel();StatsDisplay();MapView();}}}// 控制面板 - 修改状态@Componentstruct ControlPanel{@Consume('status')status:string;@Consume('trackData')trackData:TrackData;build(){Button('开始').onClick(()=>{this.status='recording';});}}// 统计显示 - 读取状态@Componentstruct StatsDisplay{@Consume('trackData')trackData:TrackData;build(){Text(`距离:${trackData.distance.toFixed(2)}km`);}}

六、AppStorage - 应用级全局存储

除了 @Provide/@Consume,ArkUI 还提供了 AppStorage 用于应用级状态管理:

// 1. 在 Ability 中初始化exportdefaultclassEntryAbilityextendsUIAbility{onCreate():void{AppStorage.setOrCreate('token','');AppStorage.setOrCreate('userId',0);AppStorage.setOrCreate('stepGoal',10000);}}// 2. 在组件中使用@Entry@Componentstruct HomePage{@StorageLink('token')token:string='';@StorageProp('stepGoal')stepGoal:number=10000;build(){Text(`目标步数:${this.stepGoal}`);}}
API说明
@StorageLink(key)双向绑定,组件修改同步到 AppStorage
@StorageProp(key)单向绑定,组件只读
AppStorage.set()设置值
AppStorage.get<T>(key)获取值
AppStorage.setOrCreate(key)不存在时创建

七、LocalStorage - 页面级共享

LocalStorage 是 Ability 或页面级别的共享存储:

// 创建页面级存储letlocalStorage=newLocalStorage({'pageTitle':'徒步迹','pageType':'home',});// 在页面中使用@Entry(localStorage)@Componentstruct HomePage{@LocalStorageLink('pageTitle')title:string='';build(){Text(this.title);}}

八、状态管理选择指南

应用级全局数据? ├── 是 → AppStorage(token、用户信息、设置) └── 否 → 组件间层级? ├── 跨多级 → @Provide/@Consume(页面级共享状态) ├── 父子 → @Prop/@Link └── 本组件 → @State

九、总结

@Provide/@Consume 是解决跨级组件通信的利器,配合 AppStorage 和 LocalStorage,可以应对各种状态管理场景。在徒步迹 App 中,我们使用 @Provide/@Consume 管理登录状态和主题模式,后续还会用于轨迹记录的实时数据共享。

下一篇文章将学习 @Watch 和 @ObjectLink 装饰器,实现更精细的状态监听。


下一篇预告:鸿蒙原生开发手记:徒步迹 - @Watch 与 @ObjectLink 深入理解

http://www.jsqmd.com/news/1184275/

相关文章:

  • ROS2 QoS配置实战:可靠性、持久性与生命周期策略详解
  • 2026年 食品包装纸筒/线缆纸筒/纸板桶/全纸桶厂家:环保耐用与承重工艺俱佳的优质供应商 - 甄选服务推荐
  • AI暴露度评估:技术人员如何识别自动化风险与构建抗性技能
  • YOLOv8目标检测实战:从原理到吸烟识别系统完整开发指南
  • FastAPI在Windows下的服务化部署与NSSM实践
  • 全球手游买量数据分析平台大全:分梯队盘点,适配不同发行团队需求 - 短商
  • VR游戏开发实战:从零到一构建你的首个沉浸式体验
  • DDrawCompat终极教程:如何让经典DirectX游戏在现代Windows上完美运行
  • 用Sentinel-2与Python自动提取野火边界线
  • 纯C实现高斯消元求逆矩阵:支持任意阶方阵,带完整可编译源码
  • AI算力的功率墙:从芯片漏电到电网调度的全链路能效革命
  • AI大模型开发实战:从Python基础到Transformer架构完整学习路线
  • AI 基础设施的经济账:Oracle 暴跌 19%、裁员 21000 人背后的算力投资陷阱
  • 北京靠谱股权评估机构联系方式获取与全流程服务指南 - 热点品牌推荐
  • SceneMI:基于扩散模型的场景感知运动插值技术解析
  • 从抖音爆款到个人网站:手把手教你部署QQ价值评估源码
  • Web安全实战:文件上传漏洞攻防原理与纵深防御体系构建
  • 主流AI服务集成实战:OpenAI、Claude、Gemini与Grok接入指南
  • 2026年找碳化硅耐磨砖品牌厂商实用选型参考指南 - 热点品牌推荐
  • 智能光电吊舱技术解析:边缘AI在无人机安防巡检的应用实践
  • 2026年东莞本地除油剂品牌厂商采购选型实用指南 - 热点品牌推荐
  • C51单片机数码管电子钟全套开发资料(含Proteus仿真+按键/LED驱动源码)
  • 2026年塑料板材加工厂家推荐:透明热成型塑料外壳/采光罩/灯罩/塑料件加工专业供应商深度解析 - 甄选服务推荐
  • 复合材料层压板从单层参数到失效判定的一站式Python计算工具
  • ROS2 QoS服务质量控制详解:七参数原理与工业级配置实战
  • 元学习在金融领域的应用与优化实践
  • 2026年豆包推广实战:AI搜索优化与GEO本地化策略解析
  • STM32F103充电桩远程控制完整工程:Keil可直接编译,含通信、状态采集与指令下发功能
  • Day2——测试基础(质量模型)
  • Windows Server 2012 Build 7968 SKU架构解析与预发布版本特性