当前位置:   article > 正文

【OpenHarmony】ArkTS 语法基础 ⑥ ( ArkTS 状态管理 | @Link 装饰器 | 子组件定义使用 @Link 变量 | 父容器中定义 @State 变量并绑定子组件变量 )

【OpenHarmony】ArkTS 语法基础 ⑥ ( ArkTS 状态管理 | @Link 装饰器 | 子组件定义使用 @Link 变量 | 父容器中定义 @State 变量并绑定子组件变量 )



在这里插入图片描述


参考文档 : <HarmonyOS第一课>ArkTS开发语言介绍

@Link 装饰器 参考文档 : https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-link-0000001524297305-V2


博客源码 : https://download.csdn.net/download/han1202012/89401441


@State 装饰器 修饰的 状态数据 只能绑定 自定义组件 内部的 UI 组件 , 如果要改变 父容器 中的组件 , 就需要使用其它的 装饰器 ,

本篇博客中 介绍的 @Link 装饰器 , 可以 在 子组件 中 使用 @Link 装饰器 绑定 父容器 的 @State 状态数据 ;





一、ArkTS 状态管理 - @Link 装饰器




1、@Link 装饰器


在 子组件中 使用 @Link 装饰器 装饰的变量 , 可以和 父容器组件中的 @State 变量 进行双向绑定 ,

父容器 的 @State 变量 和 子组件 @Link 变量 , 不论是哪一方发生了改变 , 都会通知另一方 ;


子组件 中 @Link 装饰 的 变量 如果发生了修改 , 相应绑定的 父容器 中的 @State 装饰的变量 也会发生改变 , 从而触发 父容器 的 build 函数 , 重新渲染 整个父容器 的所有组件 ;


2、子组件定义 @Link 变量


在 子组件 MyComponent 中 , 定义 isSonSelected: boolean 变量 , 使用 @Link 装饰器 修饰 该变量 ;

@Component
export struct MyComponent {
  // 子组件中的要关联父容器 @State 状态变量 的 变量
  @Link isSonSelected: boolean;
  • 1
  • 2
  • 3
  • 4

特别注意 : 在 子组件 中 , 不能对 @Link 变量进行初始化 , 否则会报如下错误 ;

Variables decorated by '@Link', '@Consume', and '@ObjectLink' cannot be initialized locally. <ArkTSCheck>
由“@Link”、“@Consume”和“@ObjectLink”修饰的变量不能在本地初始化。< ArkTSCheck >
  • 1
  • 2

在这里插入图片描述


3、子组件中使用 @Link 变量


在 子组件 中的 build 函数中 , 使用该 isSonSelected: boolean 变量 进行 UI 渲染 ,

      // 与父容器关联的子组件
      Text('子组件 : ' + this.isSonSelected)
        .fontSize(20)
        .fontColor(this.isSonSelected ? Color.Yellow : Color.White)
        .backgroundColor(Color.Black)
        .onClick(() => {
          if (this.isSonSelected) {
            this.isSonSelected = false;
          } else {
            this.isSonSelected = true;
          }
        })//onClick(
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4、父容器中定义 @State 变量


在父容器中 , 使用 @State 装饰器 修饰 isFatherSelected: boolean 变量 , 这个变量必须初始化 ;

@Entry
@Component
struct Example {

  // 父容器中的状态数据
  @State isFatherSelected: boolean = false;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

特别注意 : 使用 @State 装饰器 修饰的 变量 必须 进行初始化 , 否则会报如下错误 ;

Variables decorated by '@State', '@StorageLink', '@StorageProp', '@LocalStorageLink', '@LocalStorageProp' and '@Provide' must be initialized locally.'@State''@StorageLink''@StorageProp''@LocalStorageLink''@LocalStorageProp''@提供'装饰的变量必须在本地初始化。
  • 1
  • 2

在这里插入图片描述


5、父容器中绑定 @State 变量和 @Link 变量


在 父容器 中 , 创建子组件 ,

如果 子组件 中有 @Link 状态变量 , 则必须在 创建子组件中为 子组件 @Link 变量 设置一个绑定的 父容器的 @State 变量 ;

绑定方法是 在 子组件的 构造函数 中 , 添加 如下参数 , 可以进行 @Link 父容器

{子组件@Link变量: $父容器@State变量}
  • 1

代码示例如下 :

  build() {
    // 必须使用布局组件包括子组件
    Column(){
      // 自定义子组件
      MyComponent({isSonSelected: $isFatherSelected});
  • 1
  • 2
  • 3
  • 4
  • 5

注意 : 如果子组件中有 @Link 变量 , 那么在 初始化该 子组件 的 构造函数中 , 必须使用 父容器的 @State 变量 绑定该子组件的 @Link 变量 ;

如果 在 子组件 的 构造函数 中 , 没有绑定 @Link 变量 , 则会报如下错误 :

'@Link' decorated 'isSonSelected' must be initialized through the component constructor. <ArkTSCheck>@Link”修饰的“isSonSelected”必须通过组件构造函数初始化。< ArkTSCheck >
  • 1
  • 2

在这里插入图片描述





二、完整代码示例




1、自定义组件代码


import hilog from '@ohos.hilog'

@Component
export struct MyComponent {
  // 要显示的文字内容
  num1: number = 80;

  // 循环渲染数据源
  numArr: number[] = [9527, 2024, 911];

  // 是否被选中
  @State isSelected: boolean = false;

  // 子组件中的要关联父容器 @State 状态变量 的 变量
  @Link isSonSelected: boolean;

  // 创建后 , build 之前回调
  aboutToAppear() {
    console.log("HSL MyComponent aboutToAppear")
  }

  // 自定义子组件
  build() {
    Column({ space: 20 }) { // 设置子组件间距为10

      // 条件渲染 使用 if else 进行渲染
      // 根据不同的条件 动态控制组件显示
      if (this.num1 >= 60) {
        Text('Text1 ' + this.num1)
          .fontSize(20)
          .fontColor(Color.White)
          .backgroundColor(Color.Red)
      } else {
        Text('Text1 ' + this.num1)
          .fontSize(20)
          .fontColor(Color.White)
          .backgroundColor(Color.Black)
      }

      // 第一个参数是数组
      // 第二个参数是子组件生成函数
      // 第三个参数是键值生成器
      ForEach(// 参数一 : 数组, 循环渲染 的 数据源
        this.numArr,
        // 参数二 : 子组件生成函数
        (item: number, index: number): void => {
          Text('Text ' + index + " " + item)
            .fontSize(20)
            .fontColor(Color.White)
            .backgroundColor(Color.Black)
        }, // (item, index) => {
        // 参数三 : 键值生成器, 为组件生成唯一稳定键值
        (item: number, index: number): string => "ForEach" + index
      ) // ForEach

      // UI 组件 的 状态管理
      Text('选中状态 : ' + this.isSelected)
        .fontSize(20)
        .fontColor(this.isSelected ? Color.Yellow : Color.White)
        .backgroundColor(Color.Black)
        .onClick(() => {
          if (this.isSelected) {
            this.isSelected = false;
          } else {
            this.isSelected = true;
          }
        })//onClick(

      // 与父容器关联的子组件
      Text('子组件 : ' + this.isSonSelected)
        .fontSize(20)
        .fontColor(this.isSonSelected ? Color.Yellow : Color.White)
        .backgroundColor(Color.Black)
        .onClick(() => {
          if (this.isSonSelected) {
            this.isSonSelected = false;
          } else {
            this.isSonSelected = true;
          }
        })//onClick(

    }
    .width('50%') // 设置 Row 的宽度
    .height('50%') // 设置 Row 的高度
    .backgroundColor(Color.Pink)
    .alignItems(HorizontalAlign.Center) // 水平居中
    .justifyContent(FlexAlign.Center) // 垂直居中
  }

  // build 之后 , 销毁前回调
  aboutToDisappear() {
    console.log("HSL MyComponent aboutToDisappear")
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

2、父容器组件代码


// 导入外部自定义子组件
import {MyComponent} from '../view/MyComponent';

@Entry
@Component
struct Example {

  // 父容器中的状态数据
  @State isFatherSelected: boolean = false;

  aboutToAppear(){
    console.log("HSL Example aboutToAppear")
  }

  onPageShow() {
    console.log("HSL Example onPageShow")
  }

  onBackPress() {
    console.log("HSL Example onBackPress")
  }

  build() {
    // 必须使用布局组件包括子组件
    Column(){
      // 自定义子组件
      MyComponent({isSonSelected: $isFatherSelected});

      // 另外的子组件
      Text('父容器状态 : ' + this.isFatherSelected)
        .fontSize(20)
        .fontColor(this.isFatherSelected ? Color.Yellow : Color.White)
        .backgroundColor(Color.Black)
    }
  }

  onPageHide() {
    console.log("HSL Example onPageHide")
  }

  aboutToDisappear(){
    console.log("HSL Example aboutToDisappear")
  }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

3、执行结果


点击 子组件 中的 使用了 @Link 变量 进行渲染的 UI 组件 , 并在该 UI 组件的点击事件中 改变了 @Link 变量的值 ;

改变了子组件 @Link 变量的值 , 则 父容器 中 与之绑定的 @State 变量 也要进行修改 ,

从而 将 父容器 中 使用 @State 变量 进行渲染的 UI 组件 也进行了刷新 ,

最终 点击 子组件 后 , 子组件本身 与 父容器 中的其它组件 都发生了改变 ;


执行效果如下 :
在这里插入图片描述

进入界面后 , 默认的状态如下 , 父容器 中的 @State 变量值为 false , 子组件中的 @Link 变量 在 初始化时 , 自动赋值为 父容器 中的 @State 变量的值 , 此时样式如下 :

在这里插入图片描述

点击子组件后 , 子组件中的 @Link 变量变为 true , UI 进行重新刷新 ,

相应 绑定的 父容器 @State 变量也变为 true , UI 刷新 , 父容器中的其它子组件发生了相应的改变 ;

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/682069
推荐阅读
相关标签
  

闽ICP备14008679号