@Provide和@Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于@State/@Link装饰器修饰的 父子组件之间通过命名参数机制传递,@Provide和@Consume摆脱参数传递机制的束缚,实现跨层级传递。
其中@Provide装饰的变量是在祖先节点中,可以理解为被“提供”给后代的状态变量。@Consume装饰的变量是在后代组件中,去“消费(绑定)”祖先节点提供的变量。
@Provide/@Consume装饰的状态变量有以下特性:
- @Provide装饰的状态变量自动对其所有后代组件可用,即该变量被“provide”给他的后代组件。由此可见,@Provide的方便之处在于,开发者不需要多次在组件之间传递变量。
- 后代通过使用@Consume去获取@Provide提供的变量,建立在@Provide和@Consume之间的双向数据同步,与@State/@Link不同的是,前者可以在多层级的父子组件之间传递。
- @Provide和@Consume可以通过相同的变量名或者相同的变量别名绑定,变量类型必须相同。
@Provide和@Consume通过相同的变量名或者相同的变量别名绑定时,@Provide修饰的变量和@Consume修饰的变量是一对多的关系。不允许在同一个自定义组件内,包括其子组件中声明多个同名或者同别名的@Provide装饰的变量。
例如:
@Entry
@Component
struct ProvideAndConsume {
// @State message: string = '我是父组件'
@Provide('change') message: string = '我是父组件'
build() {
Row() {
Column() {
Text(this.message).ProvideAndConsumeSty('',()=>{
this.message = "我是父组件变化后的值"
})
Divider()
// 调用子组件
ProvideAndConsumeSon()
}
.width('100%')
}
.height('100%')
}
}
@Component
struct ProvideAndConsumeSon{
build(){
Column(){
Text('我是儿子组件').ProvideAndConsumeSty(Color.Orange)
Divider()
// 调用孙子组件
ProvideAndConsumeSun()
}
}
}
@Component
struct ProvideAndConsumeSun{
@Consume change: string //数据不能初始化 类型要与绑定的@Provide的类型一致
build(){
Column(){
Text('我是孙子组件:'+this.change).ProvideAndConsumeSty(Color.Red,()=>{
this.change = "我是孙子组件变化后的值"
})
}
}
}
@Extend(Text) function ProvideAndConsumeSty(color?: string|Color,click?:()=>void){
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor(color)
.margin({
top:15,
bottom:15
})
.onClick(() => {
click()
})
}
下图是代码运行的效果
然后点击"我是父组件"文字
然后点击"孙子组件"文字