0
点赞
收藏
分享

微信扫一扫

HarmonyOS NEXT - @Provide和@Consume

f12b11374cba 03-31 21:00 阅读 13

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

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

@Provide/@Consume是跨组件层级的双向同步。在阅读@Provide和@Consume文档前,建议开发者对UI范式基本语法和自定义组件有基本的了解。建议提前阅读:基本语法概述,声明式UI描述,自定义组件-创建自定义组件。

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

  • @Provide装饰的状态变量自动对其所有后代组件可用,即该变量被“provide”给他的后代组件。由此可见,@Provide的方便之处在于,开发者不需要多次在组件之间传递变量。
  • 后代通过使用@Consume去获取@Provide提供的变量,建立在@Provide和@Consume之间的双向数据同步,与@State/@Link不同的是,前者可以在多层级的父子组件之间传递。
  • @Provide和@Consume可以通过相同的变量名或者相同的变量别名绑定,建议类型相同,否则会发生类型隐式转换,从而导致应用行为异常。

@Provide/@Consume必须指定类型,允许装饰的变量类型如下所示:

  • Object、class、string、number、boolean、enum类型,以及这些类型的数组。
  • 支持Date类型。
  • API11及以上支持Map、Set类型。
  • 支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。
  • @Provide变量的@Consume变量的类型必须相同
  • 不支持any。
  • API11及以上支持上述支持类型的联合类型,比如string | number, string | undefined 或者 ClassA | null,示例见@Provide_and_Consume支持联合类型实例。

代码示例

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

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

代码实例 ProvideConsumePage

import { SonComponent } from './components/SonComponent';

@Entry
@Component
struct ProvideConsumePage {
  @State message: string = '第3节 @Provide和@Consume';
  @Provide('count') stateCount: number = 0

  build() {
    Column({space:10}) {
      Text(this.message)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Button('增加次数').onClick(()=>{
        this.stateCount++
      })
      Text('stateCount='+this.stateCount)

      SonComponent()
    }
    .height('100%')
    .width('100%')
  }
}

SonComponent

import { GrandsonComponent } from './GrandsonComponent'

@Component
export struct SonComponent {
  build() {
    Column({ space: 10 }) {
      Text('这是子组件')

      GrandsonComponent()
    }
    .width('100%')
    .padding(10)
    .backgroundColor(Color.Orange)
  }
}

GrandsonComponent

@Component
export struct GrandsonComponent {
  @Consume('count') grandsonCount: number

  build() {
    Column({space:10}){
      Text('孙组件')
      Button('增加次数').onClick(()=>{
        this.grandsonCount++
      })
      Text('grandsonCount='+this.grandsonCount)
    }
    .width('100%')
    .padding(10)
    .backgroundColor('#EEEEEE')
  }
}

举报

相关推荐

0 条评论