# 鸿蒙原生开发手记:徒步迹 - @Provide/@Consume 跨组件通信 > 掌握跨级组件通信,构建灵活可复用的组件体系 --- ## 一、前言 在复杂应用中,经常出现祖先组件需要向后代组件传递数据的场景。如果逐层通过 @Prop 传递,会导致"属性逐层传递"的问题(prop drilling),代码冗长且难以维护。 ArkUI 提供了 @Provide/@Consume 装饰器对,实现跨级组件通信,无需中间组件参与。 --- ## 二、@Provide/@Consume 原理 ### 2.1 基本概念 ``` @Provide 祖先组件 │ │ (自动传递) │ v @Consume 后代组件 1 @Consume 后代组件 2 ``` - `@Provide`:在祖先组件中定义,提供数据 - `@Consume`:在后代组件中声明,自动获取祖先的 Provide 数据 ### 2.2 基础用法 ```typescript // 祖先组件 - 提供数据 @Component struct AppRoot { @Provide('isLoggedIn') isLoggedIn: boolean = false; @Provide('userName') userName: string = ''; build() { Column() { // 中间组件(不需要传递任何数据) MainContent(); } } } // 中间组件 - 不接触数据 @Component struct MainContent { build() { Column() { UserProfile(); } } } // 后代组件 - 消费数据 @Component struct 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 使用变量名自动匹配: ```typescript @Component struct Ancestor { @Provide stepCount: number = 0; // 变量名作为标识 build() { Descendant(); } } @Component struct Descendant { @Consume stepCount: 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 中,登录状态需要在多个页面间共享: ```typescript // AppRoot - 应用根组件 @Entry @Component struct 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 登录页面使用 ```typescript @Component struct 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 个人中心页面使用 ```typescript @Component struct ProfilePage { @Consume('isLogged') isLogged: boolean; @Consume('currentUser') currentUser: User | null; build() { Column() { if (this.currentUser) { Text(this.currentUser.nickname)

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐