HarmonyOS NEXT开发(Beta6)@Provide和@Consume与后代组件双向同步详解

@Provide和@Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递,@Provide和@Consume摆脱参数传递机制的束缚,实现跨层级传递。

其中@Provide装饰的变量是在祖先组件中,可以理解为被“提供”给后代的状态变量。@Consume装饰的变量是在后代组件中,去“消费(绑定)”祖先组件提供的变量。

说明

  • 从API version 9开始,这两个装饰器支持在ArkTS卡片中使用。
  • 从API version 11开始,这两个装饰器支持在元服务中使用。

概述

@Provide/@Consume装饰的状态变量有以下特性:

  • @Provide装饰的状态变量自动对其所有后代组件可用,即该变量被“provide”给他的后代组件。由此可见,@Provide的方便之处在于,开发者不需要多次在组件之间传递变量。

  • 后代通过使用@Consume去获取@Provide提供的变量,建立在@Provide和@Consume之间的双向数据同步,与@State/@Link不同的是,前者可以在多层级的父子组件之间传递。

  • @Provide和@Consume可以通过相同的变量名或者相同的变量别名绑定,建议类型相同,否则会发生类型隐式转换,从而导致应用行为异常。

// 通过相同的变量名绑定
@Provide a: number = 0;
@Consume a: number;

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

@Provide和@Consume通过相同的变量名或者相同的变量别名绑定时,@Provide装饰的变量和@Consume装饰的变量是一对多的关系。不允许在同一个自定义组件内,包括其子组件中声明多个同名或者同别名的@Provide装饰的变量,@Provide的属性名或别名需要唯一且确定,如果声明多个同名或者同别名的@Provide装饰的变量,会发生运行时报错。

装饰器说明

@State的规则同样适用于@Provide,差异为@Provide还作为多层后代的同步源。

@Provide变量装饰器 说明
装饰器参数

别名:常量字符串,可选。

如果指定了别名,则通过别名来绑定变量;如果未指定别名,则通过变量名绑定变量。

同步类型

双向同步。

从@Provide变量到所有@Consume变量以及相反的方向的数据同步。双向同步的操作与@State和@Link的组合相同。

允许装饰的变量类型

Object、class、string、number、boolean、enum类型,以及这些类型的数组。

支持Date类型。

API11及以上支持Map、Set类型。

支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。

必须指定类型。

@Provide变量的@Consume变量的类型必须相同。

支持类型的场景请参考观察变化

不支持any。

API11及以上支持上述支持类型的联合类型,比如string | number, string | undefined 或者 ClassA | null

注意

当使用undefined和null的时候,建议显式指定类型,遵循TypeScript类型校验,比如:@Provide a : string | undefined = undefined是推荐的,不推荐@Provide a: string = undefined。

被装饰变量的初始值 必须指定。
支持allowOverride参数 允许重写,只要声明了allowOverride,则别名和属性名都可以被Override。示例见@Provide支持allowOverride参数。
@Consume变量装饰器 说明
装饰器参数

别名:常量字符串,可选。

如果提供了别名,则必须有@Provide的变量和其有相同的别名才可以匹配成功;否则,则需要变量名相同才能匹配成功。

同步类型 双向:从@Provide变量(具体请参见@Provide)到所有@Consume变量,以及相反的方向。双向同步操作与@State和@Link的组合相同。
允许装饰的变量类型

Object、class、string、number、boolean、enum类型,以及这些类型的数组。

支持Date类型。

支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。必须指定类型。

@Provide变量和@Consume变量的类型必须相同。

@Consume装饰的变量,在其父组件或者祖先组件上,必须有对应的属性和别名的@Provide装饰的变量。

支持类型的场景请参考

HarmonyOS ArkTS 中,`@Provide` `@Consume` 是用于实现跨层级组件之间数据同步的装饰器,特别适用于需要在多个层级之间传递状态数据的场景。`@Provide` 用于在祖先组件中声明一个状态变量,而 `@Consume` 则用于在后代组件中引用该变量,从而实现双向数据同步,摆脱了传统的父子组件间通过参数传递数据的限制[^2]。 ### 使用方式语法 `@Provide` 通常用于父组件或祖先组件中,标记一个状态变量,并使其对所有后代组件可见。该变量在祖先组件中被定义,并可以被多个层级的子组件访问修改。 ```ts @Component struct ParentComponent { @Provide count: number = 0; build() { Column() { Text(`当前计数: ${this.count}`) Button('增加计数') .onClick(() => { this.count += 1; }) ChildComponent() } } } ``` 在子组件中,使用 `@Consume` 装饰器绑定到 `@Provide` 相同的变量名,即可实现对该状态的访问修改。 ```ts @Component struct ChildComponent { @Consume count: number; build() { Column() { Text(`子组件中的计数: ${this.count}`) Button('子组件增加计数') .onClick(() => { this.count += 1; }) } } } ``` 上述代码中,点击父组件或子组件的按钮,都会同步更新 `count` 的值,并在两个组件中反映出来,实现了跨层级的双向数据绑定[^3]。 ### 响应式双向同步机制 `@Provide` `@Consume` 的一个重要特性是支持响应式更新。当 `@Provide` 声明的变量发生变化时,所有通过 `@Consume` 引用该变量的组件都会自动更新其 UI。这种机制使得在复杂组件结构中维护共享状态变得更为简单高效。 ### 适用场景 该机制特别适用于以下几种情况: - **跨层级状态共享**:当多个组件层级之间需要共享某个状态时,例如全局主题、用户登录状态等。 - **动态 UI 更新**:当某个状态的变化需要在多个组件同步更新时,如计数器、进度条等。 - **避免冗长的参数传递**:在传统的父子组件通信中,往往需要通过多层组件传递参数,而使用 `@Provide` `@Consume` 可以跳过中间层级,直接在需要的地方注入状态[^1]。 ### 注意事项 - `@Provide` `@Consume` 必须使用相同的变量名进行绑定,否则无法正确建立连接。 - 不建议在大量组件中滥用该机制,以免造成状态管理混乱,难以维护。 - 若状态需要在多个不相关的组件之间共享,建议结合全局状态管理方案,如使用 `@State` `@Link` 或者更高级的状态管理库。 ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值