【鸿蒙实战开发】HarmonyOS状态管理之@Link

201 篇文章 0 订阅
201 篇文章 0 订阅

前言

在前面两篇状态管理相关的文章中,我们分别讲解了 @State 和 @Prop 两个状态管理装饰器的作用和基本使用。@State 状态管理装饰器是最基本的状态管理装饰器,组件使用其修饰的变量,组件的更新可以随着变量的变化而更新;@Prop 状态管理装饰器则是用于父子组件之间的单向同步。
本篇文章要讲解的 @Link 状态管理装饰器则是用于父子之间的双向同步管理。下面看下该状态管理修饰器的基本使用。

@Link 的基本使用

假设我们有一个需求:有一个用户展示页面,可以展示用户的默认用户名,也可以在子组件的编辑框去修改默认用户名,且修改时要同步修改父组件展示的用户名。
要实现这个需求,首先我们定义一个子组件用来编辑父组件传递进来的用户名,具体代码如下:

@Component
struct UserDetail {
  @Link userName: string;
  build() {
    TextArea({ text: this.userName })
      .onChange((value: string) => {
        this.userName = value
      })
  }
}

这里我们定义子组件的名字为 UserDetail,它包含一个 @Link 状态管理修饰符修饰的变量 - userName。它的内部由一个可编辑的输入框 TextArea 组成,我们在输入框的 onChange 回调中去同步修改 this.userName 的值。由于 userName 是由 @Link 修饰的,所以这个修改会同步修改到父组件中。
接着,就是编写父组件来显示用户名,具体代码如下:

@Entry
@Component
struct Index {
  @State userName: string = "默认用户名";

  build() {
    Column() {
      Text(this.userName)
      Blank().height(10)
      UserDetail({userName: this.userName})

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

在父组件中,首先定义一个 @State 状态管理修饰符修饰 userName。然后使用 Text 组件来显示当前的用户名,最后将状态管理修饰符修饰的变量传递给子组件 - UserDetail。Blank 组件仅是间隔一下,没有什么别的作用。
效果图如下:
在这里插入图片描述

需要注意的是,在父组件中,userName 一定要是状态管理修饰符修饰的,普通变量是无法进行父子组件之间的数据更新同步的,即使你子组件中使用了 @Link。并且这种写法编译器也是不允许的,会报以下错误:Assigning the attribute ‘userName’ to the ‘@Link’ decorated attribute ‘userName’ is not allowed. 。

具体规则

初始化方式

@Link 状态管理修饰符修饰的变量必须由父组件传递,不允许本地初始化。如果本地初始化的话编译器会报错。
比如下面的代码:

@Link userName: string = "";

编译器会报以下错误:
Variables decorated by ‘@Link’, ‘@Consume’, and ‘@ObjectLink’ cannot be initialized locally.
实际上,它即使支持本地初始化也没有意义,因为它的作用是用于父子组件同步的,如果父组件不传值,那还同步个啥。。。

支持类型

它支持的类型和 @Prop 的类型一致,都是以下的类型:

●基础类型:string、number、boolean、enum及相关类型的数组。
●对象类型:Object、class、Date 及相关类型的数据。
●集合类型:Map、Set(API 11 以上才支持)。
●联合类型:支持上述类型的联合类型,比如:string | number。

限制

@Link 状态管理修饰符不可以在 @Entry 修饰的自定义组件使用,原因也很好理解,因为它是用于父子组件双向同步的,而 @Entry 修饰的是入口组件,并没有父组件。如果在 @Entry 修饰的自定义组件使用@Link 状态管理修饰符,虽然编译器不会报错,但会报运行时错误:
Error message:undefined ‘userName1’[0] <@Component ‘Index’[4]>: constructor: source variable in parent/ancestor @Component must be defined. Application error!

写在最后

●如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我两个小忙:
●点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
●关注小编,同时可以期待后续文章ing ,不定期分享原创知识。

在这里插入图片描述

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值