鸿蒙Harmony--状态管理器--双向同步@Link详解

你这一生最重要的责任,就是保护好自己脆弱的梦想,熬过被忽略的日子,就轮到你上场了。

如何解决大模型的「幻觉」问题?

目录

一,定义

二,装饰器使用规则说明

三,变量的传递/访问规则说明

 四,使用

①简单使用

 ②复杂类型的使用

五,注意事项

@Link装饰状态变量类型错误

一,定义

子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。

!注意:@Link装饰器不能在@Entry装饰的自定义组件中使用。

二,装饰器使用规则说明

@Link变量装饰器说明
装饰器参数
同步类型双向同步。
父组件中@State, @StorageLink和@Link 和子组件@Link可以建立双向数据同步,反之亦然。
允许装饰的变量类型Object、class、string、number、boolean、enum类型,以及这些类型的数组。
支持Date类型。
类型必须被指定,且和双向绑定状态变量的类型相同。
不支持any,不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。
说明:
不支持Length、ResourceStr、ResourceColor类型,Length、ResourceStr、ResourceColor为简单类型和复杂类型的联合类型。
被装饰变量的初始值无,禁止本地初始化。

三,变量的传递/访问规则说明

传递/访问说明
从父组件初始化和更新必选。与父组件@State, @StorageLink和@Link 建立双向绑定。允许父组件中@State、@Link、@Prop、@Provide、@Consume、@ObjectLink、@StorageLink、@StorageProp、@LocalStorageLink和@LocalStorageProp装饰变量初始化子组件@Link。
从API version 9开始,@Link子组件从父组件初始化@State的语法为Comp({ aLink: this.aState })。同样Comp({aLink: $aState})也支持。
用于初始化子组件允许,可用于初始化常规变量、@State、@Link、@Prop、@Provide。
是否支持组件外访问私有,只能在所属组件内访问。

 四,使用

  • 当装饰的数据类型为boolean、string、number类型时,可以同步观察到数值的变化

  • 当装饰的数据类型为class或者Object时,可以观察到赋值和属性赋值的变化,即Object.keys(observedObject)返回的所有属性

  • 当装饰的对象是array时,可以观察到数组添加、删除、更新数组单元的变化

  • 当装饰的对象是Date时,可以观察到Date整体的赋值,同时可通过调用Date的接口setFullYearsetMonthsetDatesetHourssetMinutessetSecondssetMillisecondssetTimesetUTCFullYearsetUTCMonthsetUTCDatesetUTCHourssetUTCMinutessetUTCSecondssetUTCMilliseconds 更新Date的属性。

@Link装饰的变量和其所属的自定义组件共享生命周期。

为了了解@Link变量初始化和更新机制,有必要先了解父组件和拥有@Link变量的子组件的关系,初始渲染和双向更新的流程(以父组件为@State为例)。

  1. 初始渲染:执行父组件的build()函数后将创建子组件的新实例。初始化过程如下:

    1. 必须指定父组件中的@State变量,用于初始化子组件的@Link变量。子组件的@Link变量值与其父组件的数据源变量保持同步(双向数据同步)。
    2. 父组件的@State状态变量包装类通过构造函数传给子组件,子组件的@Link包装类拿到父组件的@State的状态变量后,将当前@Link包装类this指针注册给父组件的@State变量。
  2. @Link的数据源的更新:即父组件中状态变量更新,引起相关子组件的@Link的更新。处理步骤:

    1. 通过初始渲染的步骤可知,子组件@Link包装类把当前this指针注册给父组件。父组件@State变量变更后,会遍历更新所有依赖它的系统组件(elementid)和状态变量(比如@Link包装类)。
    2. 通知@Link包装类更新后,子组件中所有依赖@Link状态变量的系统组件(elementId)都会被通知更新。以此实现父组件对子组件的状态数据同步。
  3. @Link的更新:当子组件中@Link更新后,处理步骤如下(以父组件为@State为例):

    1. @Link更新后,调用父组件的@State包装类的set方法,将更新后的数值同步回父组件。
    2. 子组件@Link和父组件@State分别遍历依赖的系统组件,进行对应的UI的更新。以此实现子组件@Link同步回父组件@State。

①简单使用

组件:

@Component
export default struct PropTest {
 
  @Link aaa:string

  build() {
    Row() {
      Column() {
        Text("aaa="+this.aaa)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.aaa ="999"
          })
      }.width('100%')
    }.height('100%')
  }
}

 使用:

import PropTest from './PropTest';

@Entry
@Component
struct Index {

  @State aaa:string ="222"

  build() {
    Column(){
      Text("aaa:"+this.aaa)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.aaa ="666"
         
        })
      PropTest({aaa:this.aaa})
    }
  }
}

运行:

点击aaa:222点击aaa=666

 ②复杂类型的使用

数据类:

export default class YuanZhen {

  public name: string = 'YuanZhen';

  public age: number = 18;

  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
}
import YuanZhen from './YuanZhen';

export default class Yuan {

  public number: number = 1;
  public yuanZhen: YuanZhen = new YuanZhen('yuanzhen', 18);

  constructor(number: number, yuanZhen: YuanZhen) {
    this.number = number
    this.yuanZhen = yuanZhen
  }
}

组件类:

import YuanZhen from './bean/YuanZhen'

@Component
export default struct YzComponent {
  @State yuanZhen:YuanZhen=new YuanZhen("袁震",18)

  build() {
    Row() {
      Column() {
        Text("name:"+this.yuanZhen.name+"\nage:"+this.yuanZhen.age)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

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

父组件:

import Yuan from './bean/Yuan';
import YuanZhen from './bean/YuanZhen';
import PropTest from './PropTest';

@Entry
@Component
struct Index {

  @State yuan:Yuan=new Yuan(2,new YuanZhen("袁震",18))

  build() {
    Column(){
      Text("父name:" + this.yuan.yuanZhen.name+"\nage:"+this.yuan.yuanZhen.age+"\nnumber:"+this.yuan.number)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.yuan.number=1
          this.yuan.yuanZhen.age=32
          this.yuan.yuanZhen.name="袁震1"
        })
      PropTest({yuan:this.yuan})
    }
  }
}

使用:

点击父:

点击子:

五,注意事项

@Link装饰状态变量类型错误

在子组件中使用@Link装饰状态变量需要保证该变量与数据源类型完全相同,且该数据源需为被诸如@State等装饰器装饰的状态变量。

  • 27
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁震

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值