组件与组件之间除了父子关系以外,还有多级嵌套的关系,例如爷爷组件和孙子组件。因此组件之间的通信方式,除了父子组件通信外,还有跨层级组件之间的通信。
一、跨级通信的介绍
1、@Provide和@Consume
ArkTS中提供了@Provide和@Consume,来实现祖先组件与后代组件的双向数据同步。不同于前面学习的父子组件之间通过命名参数机制传递,@Provide和@Consume摆脱参数传递机制的束缚,实现跨层级传递。
其中:
- @Provide装饰的变量是在祖先组件中,可以理解为被“提供”给后代的状态变量。
- @Consume装饰的变量是在后代组件中,去“消费(绑定)”祖先组件提供的变量。
2、特点
@Provide和@Consume传递的数据有以下几个特点:
- 祖先组件修改@Provide定义的数据,后代组件中的数据也会发生改变,内外组件同步更新;
- 后代组件修改@Consume接收的数据,祖先组件中的数据也会发生改变,内外组件同步更新;
二、跨级通信的使用
我们以MyPageA作为顶层祖先组件,MyComponentB作为中间组件,即MyPageA的子组件,MyComponentC作为最里层的孙子组件,即MyComponentB的子组件。MyPageA和MyComponentC之间形成多级嵌套关系。
1、后代组件接收数据
在多级嵌套的后代组件中,通过@Consume装饰器来接收祖先组件传递的数据:
@Component
export struct MyComponentC {
// 通过相同的变量名 count 来传递和接收
@Consume count: number;
// 通过相同的变量别名 name 来传递和接收
@Consume('name') studentName: string;
build() {
Column() {
Text(`${this.count}`)
Text(`${this.studentName}`)
}
}
}
2、祖先组件传递数据
在多级嵌套的祖先组件中,通过@Provide装饰器来给后代组件传递数据:
import { MyComponentB } from '../components/MyComponentB'
@Entry
@Component
struct MyPageA {
// 通过相同的变量名 count 来传递和接收
@Provide count: number = 10;
// 通过相同的变量别名 name 来传递和接收
@Provide('name') username: string = "张三";
build() {
Column() {
MyComponentB()
}
}
}
三、跨层级修改数据
祖先组件传递数据给后代组件后,祖先组件和后代组件都可以修改数据,且数据修改后,所有的相关组件都会更新。
例如我们在后代组件 MyComponentC 中对数据进行修改,不仅 MyComponentC 组件自己会更新,其所有的祖先组件也会同步更新:
@Component
export struct MyComponentC {
// 通过相同的变量名 count 来传递和接收
@Consume count: number;
build() {
Column() {
Text(`后代组件的数据:${this.count}`)
Button('按钮').onClick((event: ClickEvent) => {
// 修改数据
this.count++;
})
}
}
}
代码执行后效果如下: