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

发布时间:2024年01月11日

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

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

目录

一,定义

二,装饰器使用规则说明

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

?四,使用

①简单使用

?②复杂类型的使用

五,注意事项

@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的接口setFullYear,?setMonth,?setDate,?setHours,?setMinutes,?setSeconds,?setMilliseconds,?setTime,?setUTCFullYear,?setUTCMonth,?setUTCDate,?setUTCHours,?setUTCMinutes,?setUTCSeconds,?setUTCMilliseconds?更新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等装饰器装饰的状态变量。

文章来源:https://blog.csdn.net/y2653904/article/details/135515304
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。