前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【OpenHarmony】ArkTS 语法基础 ⑥ ( ArkTS 状态管理 | @Link 装饰器 | 子组件定义使用 @Link 变量 | 父容器中定义 @State 变量并绑定子组件变量 )

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

作者头像
韩曙亮
发布2024-06-07 15:28:04
1970
发布2024-06-07 15:28:04
举报

参考文档 : <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 装饰器 修饰 该变量 ;

代码语言:javascript
复制
@Component
export struct MyComponent {
  // 子组件中的要关联父容器 @State 状态变量 的 变量
  @Link isSonSelected: boolean;

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

代码语言:javascript
复制
Variables decorated by '@Link', '@Consume', and '@ObjectLink' cannot be initialized locally. <ArkTSCheck>
由“@Link”、“@Consume”和“@ObjectLink”修饰的变量不能在本地初始化。< ArkTSCheck >

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

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

代码语言:javascript
复制
      // 与父容器关联的子组件
      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(

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

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

代码语言:javascript
复制
@Entry
@Component
struct Example {

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

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

代码语言:javascript
复制
Variables decorated by '@State', '@StorageLink', '@StorageProp', '@LocalStorageLink', '@LocalStorageProp' and '@Provide' must be initialized locally.
由'@State', '@StorageLink', '@StorageProp', '@LocalStorageLink', '@LocalStorageProp'和'@提供'装饰的变量必须在本地初始化。

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

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

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

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

代码语言:javascript
复制
{子组件@Link变量: $父容器@State变量}

代码示例如下 :

代码语言:javascript
复制
  build() {
    // 必须使用布局组件包括子组件
    Column(){
      // 自定义子组件
      MyComponent({isSonSelected: $isFatherSelected});

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

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

代码语言:javascript
复制
'@Link' decorated 'isSonSelected' must be initialized through the component constructor. <ArkTSCheck>
“@Link”修饰的“isSonSelected”必须通过组件构造函数初始化。< ArkTSCheck >

二、完整代码示例

1、自定义组件代码

代码语言:javascript
复制
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")
  }
}

2、父容器组件代码

代码语言:javascript
复制
// 导入外部自定义子组件
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")
  }

}

3、执行结果

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

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

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

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

执行效果如下 :

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、ArkTS 状态管理 - @Link 装饰器
    • 1、@Link 装饰器
      • 2、子组件定义 @Link 变量
        • 3、子组件中使用 @Link 变量
          • 4、父容器中定义 @State 变量
            • 5、父容器中绑定 @State 变量和 @Link 变量
            • 二、完整代码示例
              • 1、自定义组件代码
                • 2、父容器组件代码
                  • 3、执行结果
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档