第七讲_ArkTS装饰器(四)

本文详细介绍了ArkTS中的Provide、Consume、Observed和ObjectLink装饰器,重点讲解了它们的特点、使用示例以及变量传递规则,帮助开发者在状态数据跨层级传递和组件间双向同步时更有效地运用这些工具。
摘要由CSDN通过智能技术生成

1. @Provide装饰器和@Consume装饰器

上一篇博文ArkTS装饰器(三)中,介绍的@Prop装饰器和@Link装饰器都是父子间的同步。@Provide装饰器和@Consume装饰器,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。

1.1 @Provide装饰器和@Consume装饰器特点

  1. @Provide装饰的状态变量自动对其所有后代组件可用。
  2. 后代通过使用@Consume去获取@Provide提供的变量。
  3. @Provide@Consume之间是双向数据同步。
  4. @Provide变量在声明时必须指定类型和本地初始化。
  5. @Consume变量在声明时必须指定类型,可以不本地初始化,但禁止父组件初始化。

1.2 @Provide装饰器和@Consume装饰器使用示例

组件Parent中引入了Child组件,Child组件中引入了Grandson组件,三层关系之间通过@Provide@Consume来实现跨层的数据双向同步。

@Entry
@Component
struct Parent {
  // 定义一个状态变量
  @Provide count: number = 0;

  build() {
    Column() {
      // 使用自定义Child组件
      Child()
      Text(`Parent组件中count=${this.count}`)
      // Button是系统组件,添加一个点击事件,点击一次就给count + 1
      Button("Parent组件中的点击+1")
        .onClick(() => {
          this.count++
        })
    }
  }
}

@Component
struct Child {
  // 定义一个@Consume变量
  // 获取祖先组件中@Provide提供的变量
  @Consume count: number;

  build() {
    Column() {
      // 使用自定义Grandson组件
      Grandson()
      Text(`Child组件中count=${this.count}`)
      Button("Child组件中的点击+1")
        .onClick(() => {
          this.count++
        })
    }
  }
}

@Component
struct Grandson {
  // 获取祖先组件中@Provide提供的变量
  @Consume count: number;

  build() {
    Column() {
      Text(`Grandson组件中count=${this.count}`)
      Button("Grandson组件中的点击+1")
        .onClick(() => {
          this.count++
        })
    }
  }
}

在这里插入图片描述

1.3 @Provide变量的传递规则

父组件中哪些变量可以用来初始化子组件中的@Provide变量?
@Provide变量可以用来初始化子组件中的哪些变量?
在这里插入图片描述

1.4 @Consume变量的传递规则

@Consume变量禁止被父组件初始化。
@Consume变量可以用来初始化子组件中的哪些变量?
在这里插入图片描述

2. @Observed装饰器和@ObjectLink装饰器

上一篇博文ArkTS装饰器(三)和上文所述的装饰器仅能观察到第一层的变化,对于多层嵌套的情况,比如二维数组、数组项class、class的属性是class,它们的第二层的属性变化是无法观察到的。这个时候就需要用到@Observed/@ObjectLink装饰器。

2.1 @Observed装饰器和@ObjectLink装饰器特点

  • @Observed用于修饰类,被@Observed装饰的类,可以观察到嵌套的变化;
  • @ObjectLink用在子组件中,@ObjectLink装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。
  • @ObjectLink装饰器不能在@Entry装饰的自定义组件中使用。
  • @Observed除了搭配@ObjectLink使用,还可以搭配@Prop使用。

2.2 @Observed装饰器和@ObjectLink装饰器使用示例

示例中,this.classA.classB.namethis.classA.classB.age属于第二层变化,@State无法观察到第二层的变化,因此Parent组件中的Text不会变化。@ObjectLink可以观察到,所以Child组件中的Text会变化。

@Observed
class ClassA {
  classB: ClassB;

  constructor(classB: ClassB) {
    this.classB = classB;
  }
}

@Observed
class ClassB {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

@Entry
@Component
struct Parent {
  // 定义一个状态变量
  @State classA: ClassA = new ClassA(new ClassB("张三", 18));

  build() {
    Column() {
      // 使用自定义Child组件,父组件传参初始化子组件
      Child({classB:this.classA.classB})
      // this.classA.classB.name和this.classA.classB.age属于第二层变化,@State无法观察到第二层的变化
      Text(`Parent组件中name=${this.classA.classB.name},age=${this.classA.classB.age}`)
      // Button是系统组件,添加一个点击事件
      Button("Parent组件中的点击age+1")
        .onClick(() => {
          this.classA.classB.age += 1
        })
    }
  }
}

@Component
struct Child {
  // 定义一个@ObjectLink变量,@ObjectLink变量的类型所属类必须被@Observed修饰
  // 不可以本地初始化
  @ObjectLink classB: ClassB;

  build() {
    Column() {
      Text(`Child组件中name=${this.classB.name},age=${this.classB.age}`)
      Button("Child组件中的点击age+1")
        .onClick(() => {
          this.classB.age += 1
        })
    }
  }
}

在这里插入图片描述

2.3 @ObjectLink变量的传递规则

父组件中哪些变量可以用来初始化子组件中的@ObjectLink变量?
@ObjectLink变量可以用来初始化子组件中的哪些变量?
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值