OpenHarmony后代组件双向同步,跨层级传递:@Provide装饰器和@Consume装饰器

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

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

说明:

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

概述

@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类型。
支持类型的场景请参考 观察变化 。
不支持any,不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。
必须指定类型。@Provide变量的@Consume变量的类型必须相同。
说明:
不支持Length、ResourceStr、ResourceColor类型,Length、ResourceStr、ResourceColor为简单类型和复杂类型的联合类型。
被装饰变量的初始值 必须指定。
@Consume变量装饰器 说明
### @Provide @Consume 装饰器的作用及错误说法 在 Vue.js 或类似框架中,`@Provide` `@Consume` 装饰器用于实现组件之间的依赖注入功能。以下是关于这两个装饰器的详细说明以及可能存在的错误描述。 #### @Provide 装饰器 `@Provide` 装饰器用于将数据或方法从父组件提供给子组件。它类似于 Vue 的 `provide` 选项,但通过装饰器的形式使代码更加简洁直观。使用 `@Provide` 装饰器后,父组件可以向其后代组件(包括直接子组件间接子组件)暴露特定的数据或方法[^1]。 ```typescript import { Component, Provide } from 'vue-property-decorator'; @Component export default class ParentComponent extends Vue { @Provide() message: string = 'Hello from parent'; } ``` #### @Consume 装饰器 `@Consume` 装饰器用于在子组件中接收由父组件通过 `@Provide` 提供的数据或方法。它类似于 Vue 的 `inject` 选项,允许子组件访问父组件提供的内容[^2]。 ```typescript import { Component, Consume } from 'vue-property-decorator'; @Component export default class ChildComponent extends Vue { @Consume() message!: string; mounted() { console.log(this.message); // 输出 "Hello from parent" } } ``` #### 错误的说法 以下是一些关于 `@Provide` `@Consume` 装饰器的常见错误描述: 1. **错误说法:`@Provide` 只能在根组件中使用** 这是错误的。`@Provide` 可以在任何组件中使用,不仅限于根组件。只要该组件有需要提供给后代组件的数据或方法,就可以使用 `@Provide` 装饰器[^3]。 2. **错误说法:`@Consume` 必须与 `@Provide` 在同一文件中定义** 这是错误的。`@Consume` 只需要确保能够找到由 `@Provide` 提供的内容即可,无论它们是否在同一文件中定义。只要父子组件关系正确,`@Consume` 就能正常工作[^4]。 3. **错误说法:`@Provide` `@Consume` 只能传递字符串类型的数据** 这是错误的。`@Provide` `@Consume` 可以传递任意类型的数据,包括对象、数组、函数等[^5]。 4. **错误说法:`@Provide` 提供的数据不会响应式更新** 这是错误的。当使用 `@Provide` 提供的数据发生变化时,通过 `@Consume` 接收的子组件会自动感知到变化并重新渲染[^6]。 #### 注意事项 - `@Provide` `@Consume` 的组合适用于跨层级组件通信场景,但在简单的父子组件通信中,推荐优先使用 `props` `events`。 - 确保 `@Provide` 提供的数据具有明确的生命周期管理,避免内存泄漏问题。 ### 示例代码 以下是一个完整的示例,展示如何使用 `@Provide` `@Consume` 装饰器进行组件间通信: ```typescript // 父组件 import { Component, Provide } from 'vue-property-decorator'; @Component export default class ParentComponent extends Vue { @Provide() greeting: string = 'Hello'; changeGreeting() { this.greeting = 'Hi'; } } // 子组件 import { Component, Consume } from 'vue-property-decorator'; @Component export default class ChildComponent extends Vue { @Consume() greeting!: string; mounted() { console.log(this.greeting); // 输出 "Hello" } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值