鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解

这篇具有很好参考价值的文章主要介绍了鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 经历的越多,越喜欢简单的生活,干净的东西,清楚的感觉,有结果的事,和说到做到的人。把圈子变小,把语放缓,把心放宽,用心做好手边的事儿,该有的总会有的!

目录

一,定义

二,装饰器说明

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

 四,使用

1,简单对象的使用

2,嵌套对象的使用

3,数组对象的使用

一,定义

之前所讲的装饰器仅能观察到第一层的变化,但是在实际应用开发中,应用会根据开发需要,封装自己的数据模型。对于多层嵌套的情况,比如二维数组,或者数组项class,或者class的属性是class,他们的第二层的属性变化是无法观察到的。这就引出了@Observed/@ObjectLink装饰器。

@ObjectLink和@Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步:

①被@Observed装饰的类,可以被观察到属性的变化;

②子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class object中的属性,这个属性同样也需要被@Observed装饰。

③单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。

限制条件:

①使用@Observed装饰class会改变class原始的原型链,@Observed和其他类装饰器装饰同一个class可能会带来问题。

②@ObjectLink装饰器不能在@Entry装饰的自定义组件中使用。

二,装饰器说明

@Observed类装饰器 说明
装饰器参数
类装饰器 装饰class。需要放在class的定义前,使用new创建类对象。
@ObjectLink变量装饰器 说明
装饰器参数
同步类型 不与父组件中的任何类型同步变量。
允许装饰的变量类型 必须为被@Observed装饰的class实例,必须指定类型。
不支持简单类型,可以使用@Prop。
支持继承Date或者Array的class实例
@ObjectLink的属性是可以改变的,但是变量的分配是不允许的,也就是说这个装饰器装饰变量是只读的,不能被改变。
被装饰变量的初始值 不允许。

!注意:

@ObjectLink装饰的变量不能被赋值,如果要使用赋值操作,请使用@Prop。

①@Prop装饰的变量和数据源的关系是单向同步,@Prop装饰的变量在本地拷贝了数据源,所以它允许本地更改,如果父组件中的数据源有更新,@Prop装饰的变量本地的修改将被覆盖;

②@ObjectLink装饰的变量和数据源的关系是双向同步,@ObjectLink装饰的变量相当于指向数据源的指针。禁止对@ObjectLink装饰的变量赋值,如果一旦发生@ObjectLink装饰的变量的赋值,则同步链将被打断。因为@ObjectLink修饰的变量通过数据源(Object)引用来初始化。对于实现双向数据同步的@ObjectLink,赋值相当于更新父组件中的数组项或者class的属性,TypeScript/JavaScript不能实现,会发生运行时报错。

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

@ObjectLink传递/访问 说明
从父组件初始化 必须指定。
初始化@ObjectLink装饰的变量必须同时满足以下场景:
- 类型必须是@Observed装饰的class。
- 初始化的数值需要是数组项,或者class的属性。
- 同步源的class或者数组必须是@State,@Link,@Provide,@Consume或者@ObjectLink装饰的数据。
与源对象同步 双向。
可以初始化子组件 允许,可用于初始化常规变量、@State、@Link、@Prop、@Provide

 四,使用

注意,@Observed必须在ets文件中使用,在ts文件中不允许使用

1,简单对象的使用

用@Observed装饰数据类

@Observed
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 './bean/YuanZhen'

@Component
export default struct ProvideTest {

  @ObjectLink yuanZhen:YuanZhen

  build() {
    Row() {
      Column() {
        Text("子name:" + this.yuanZhen.name+"\nage:"+this.yuanZhen.age)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.yuanZhen.name ="袁震2"
            this.yuanZhen.age=35
          })
      }.width('100%')
    }.height('100%')
  }

}

父组件

import YuanZhen from './bean/YuanZhen';
import ProvideTest from './ProvideTest';

@Entry
@Component
struct Index {

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

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

}

注意:这里会有一个报错,Assigning the '@State' decorated attribute 'yuan' to the '@ObjectLink' decorated attribute 'yuanZhen' is not allowed. <ArkTSCheck> 是编译器的问题,但是不影响使用

运行效果:

鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙点击父鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙点击子鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙

所以, 被@Observed和@ObjectLink修饰的class可以实现父子双向绑定

2,嵌套对象的使用

用@Observed修饰的数据类:

@Observed
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';
@Observed
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 ProvideTest {

  @ObjectLink yuanZhen:YuanZhen

  build() {
    Row() {
      Column() {
        Text("子name:" + this.yuanZhen.name+"\nage:"+this.yuanZhen.age)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.yuanZhen.name ="袁震2"
            this.yuanZhen.age=35
          })
      }.width('100%')
    }.height('100%')
  }
}

父组件:

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

@Entry
@Component
struct Index {

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

  build() {
    Column(){
      Text("父name:" + this.yuan.yuanZhen.name+"\nage:"+this.yuan.yuanZhen.age)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.yuan.yuanZhen.name ="袁震1"
          this.yuan.yuanZhen.age =20
          console.info("yz----name="+this.yuan.yuanZhen.name )
        })
      ProvideTest({yuanZhen:this.yuan.yuanZhen})
    }
  }
}

运行:

鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙点击父鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙点击子鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙

点击父组件,输出:鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙

由此可见,当class为嵌套类型时,父组件的UI不会改变,但是数据会改变,子组件的UI和数据都会改变

3,数组对象的使用

子组件

import Yuan from './bean/Yuan'


@Component
export default struct ProvideTest {

  @ObjectLink yuan:Yuan

  build() {
    Row() {
      Column() {
        Text("子name:"+this.yuan.yuanZhen.name+"\nage:"+this.yuan.yuanZhen.age+"\nnumber:"+this.yuan.number)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.yuan.yuanZhen.name ="袁震子组件"
            this.yuan.yuanZhen.age=35
            console.log("yz---name:"+this.yuan.yuanZhen.name)
          })
      }.width('100%')
    }.height('100%')
  }
}

父组件

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

@Entry
@Component
struct Index {
  @State yuan:Array<Yuan>=new Array

  aboutToAppear(){
    let yuan1:Yuan =new Yuan(1,new YuanZhen("袁震1",18))
    let yuan2:Yuan =new Yuan(2,new YuanZhen("袁震2",19))
    let yuan3:Yuan =new Yuan(3,new YuanZhen("袁震3",20))
    this.yuan.push(yuan1)
    this.yuan.push(yuan2)
    this.yuan.push(yuan3)
  }

  build() {
    Column(){
      Text("父name:" + this.yuan[0].yuanZhen.name+"\nage:"+this.yuan[0].yuanZhen.age+"\nnumber:"+this.yuan[0].number)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.yuan[0].yuanZhen.name="袁震父组件"
          this.yuan[0].number =10
          this.yuan[0].yuanZhen.age=30
        })
      ProvideTest({yuan:this.yuan[0]})
    }
  }

}

运行:

鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙点击父鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙点击子鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙

可以看到,父组件不会更新本身的UI,会更新子组件的UI,子组件既不会更新自己的UI也不会更新父组件的UI。

但是,可以直接传给子组件简单类,这样可以更新子组件

子组件 

import YuanZhen from './bean/YuanZhen'

@Component
export default struct ProvideTest {

  @ObjectLink yuanZhen:YuanZhen

  build() {
    Row() {
      Column() {
        Text("子name:"+this.yuanZhen.name+"\nage:"+this.yuanZhen.age)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.yuanZhen.name ="袁震子组件"
            this.yuanZhen.age=35
            console.log("yz---name:"+this.yuanZhen.name)
          })
      }.width('100%')
    }.height('100%')
  }
}

父组件

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

@Entry
@Component
struct Index {
  @State yuan:Array<Yuan>=new Array

  aboutToAppear(){
    let yuan1:Yuan =new Yuan(1,new YuanZhen("袁震1",18))
    let yuan2:Yuan =new Yuan(2,new YuanZhen("袁震2",19))
    let yuan3:Yuan =new Yuan(3,new YuanZhen("袁震3",20))
    this.yuan.push(yuan1)
    this.yuan.push(yuan2)
    this.yuan.push(yuan3)
  }

  build() {
    Column(){
      Text("父name:" + this.yuan[0].yuanZhen.name+"\nage:"+this.yuan[0].yuanZhen.age+"\nnumber:"+this.yuan[0].number)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.yuan[0].yuanZhen.name="袁震父组件"
          this.yuan[0].number =10
          this.yuan[0].yuanZhen.age=30
        })
      ProvideTest({yuanZhen:this.yuan[0].yuanZhen})
    }
  }

}

鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙点击父鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙点击子鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解,鸿蒙开发,harmonyos,鸿蒙

父组件的ui不会改变,子组件的UI会实时更新文章来源地址https://www.toymoban.com/news/detail-790099.html

到了这里,关于鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 鸿蒙Harmony--状态管理器--@Prop详解

    纵横千里独行客,何惧前路雨潇潇。夜半浊酒慰寂寞,天明走马入红尘。且将新火试新茶,诗酒趁年华。青春以末,壮志照旧,生活以悟,前路未明。时间善变,可执着翻不了篇。时光磨我少年心,却难灭我少年志,壮士活古不活皮。加油。 目录 一,定义 二,装饰器使用规

    2024年02月01日
    浏览(51)
  • 鸿蒙Harmony--LocalStorage--页面级UI状态存储详解

    走的太急疼的是脚,逼的太紧累的是心,很多时候,慢一点也没关系,多给自己一些耐心和等待,保持热爱,当下即是未来,生活自有安排!  目录 一,定义 二,@LocalStorageProp定义 三,@LocalStorageProp装饰器使用规则说明  四,@LocalStorageProp变量的传递/访问规则说明  五,@Loc

    2024年01月20日
    浏览(35)
  • 鸿蒙Harmony--AppStorage--应用全局的UI状态存储详解

     无所求必满载而归,当你降低期待,降低欲望,往往会得到比较好的结果,把行动交给现在,用心甘情愿的态度,过随遇而安的生活,无论结果如何,都是一场惊喜的获得! 目录 一,定义 二,@StorageProp定义 三,@StorageProp装饰器使用规则说明 四,变量的传递/访问规则说明

    2024年01月17日
    浏览(38)
  • 鸿蒙Harmony-PersistentStorage--持久化存储UI状态储详解

    用简单的心境,对待复杂的人生,方能看淡得失,从容入世,潇洒自如,心变得简单了,世界也就简单了 目录 一,定义 二,限制条件 三,使用 LocalStorage和AppStorage都是运行时的内存,但是在应用退出再次启动后,依然能保存选定的结果,是应用开发中十分常见的现象,这就

    2024年01月18日
    浏览(37)
  • 系统学习Python——装饰器:类装饰器-[初探类装饰器和元类]

    分类目录:《系统学习Python》总目录 函数装饰器是如此有用,以至于Python2.X和Python3.X都扩展了这一模式,允许装饰器应用于类和函数。简而言之,类装饰器类似于函数装饰器,但它们是在一条 class 语句的末尾运行,并把一个类名重新绑定到一个可调用对象。同样,它们可以

    2024年02月19日
    浏览(29)
  • 惬意上手Python —— 装饰器和内置函数

     Python中的装饰器是一种特殊类型的函数,它允许用户在不修改原函数代码的情况下,增加或修改函数的行为。 具体来说, 装饰器的工作原理基于Python的函数也是对象这一事实,可以被赋值给变量、作为参数传递给其他函数或者作为其他函数的返回值。装饰器通常接受一个函

    2024年01月24日
    浏览(37)
  • 【鸿蒙系统学习笔记】状态管理

    资料来自官网:文档中心 在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染,在ArkUI中统称为状态管理机制。 View

    2024年02月21日
    浏览(30)
  • 鸿蒙开发之状态管理

    @State装饰的变量,会和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。 在状态变量相关装饰器中,@State是最基础的,使变量拥有状态属性的装饰器,它也是大部分状态变量的数据源。 装饰器使用规则 同步类型:不与父组件中任何类型的变量同步。 允

    2024年01月20日
    浏览(40)
  • 鸿蒙开发系列教程(七)--ArkTS语言:状态管理

    如果希望构建一个动态的、有交互的界面,就需要引入“状态”的概念 状态管理机制:在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化

    2024年01月20日
    浏览(41)
  • 【HarmonyOS】鸿蒙开发之状态管理——第2.2章

    ArkUI 开发提供了多维度的状态管理机制。状态管理机制能使父子组件之间,爷孙组件之间数值传递,还可以跨设备传递。从数据的传递形式看,可以分为只读的单向传递和可变更的双向传递。与vue的用法特别像。 @State 有以下特征: 支持多种数据类型: class number boolean string 强类

    2024年02月21日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包