【鸿蒙实战开发】@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化

@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化

前言

为什么要有@Observed装饰器和@ObjectLink装饰器?

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

概述

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

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

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

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

注意:

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

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

装饰器说明

在这里插入图片描述

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

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

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

框架行为

●初始渲染:

●@Observed装饰的class的实例会被不透明的代理对象包装,代理了class上的属性的setter和getter方法
●子组件中@ObjectLink装饰的从父组件初始化,接收被@Observed装饰的class的实例,@ObjectLink的包装类会将自己注册给@Observed class。
●属性更新:当@Observed装饰的class属性改变时,会走到代理的setter和g

<think>好的,我现在需要帮助用户理解鸿蒙开发中的@Observed@ObjectLink装饰器的作用,并找出错误的描述选项。首先,我需要回顾用户提供的引用内容,分析每个引用的关键点,然后结合这些信息来判断哪个选项是错误的。 根据用户提供的引用内容: 引用[1]指出在子组件中给@ObjectLink装饰的变量赋值是不允许的,并给出了反例。这说明@ObjectLink变量在子组件中是只读的,不能直接修改。 引用[2]提到在子组件中尝试给@ObjectLink变量赋值,如this.testNum = new Info(47),这会导致错误,进一步验证了引用[1]的内容。 引用[3]说明@ObjectLink用于接收@Observed类的实例,并与父组件中的状态变量建立双向绑定。这里强调@Observed装饰的类或属性,以及双向绑定的特性。 引用[4]讨论了@Provide@Consume的命名唯一性,与@Observed@ObjectLink无关,可能用于干扰选项。 接下来,用户的问题是关于这两个装饰器的作用解析及判断错误描述。假设用户提供的选项中可能包含以下几点: 1. @ObjectLink变量在子组件中可以修改。 2. @Observed装饰类,而@ObjectLink用于子组件建立双向绑定。 3. @ObjectLink只能用于基本数据类型。 4. @ObjectLink需要与父组件的@State变量绑定。 根据引用内容: - 错误描述可能是选项1,因为引用[1][2]明确禁止在子组件中修改@ObjectLink变量。 - 选项2正确,引用[3]支持。 - 选项3错误,因为@ObjectLink用于对象实例,而非基本类型。 - 选项4可能正确,因为需要父组件的对应状态变量,但需确认。 但用户提供的选项中是否包含这些需要推断。假设选项中有类似选项1的说法,则错误。例如,若选项A说“@ObjectLink允许子组件直接赋值”,则A错误。 总结:错误描述是允许在子组件中给@ObjectLink变量赋值。</think>### @Observed@ObjectLink装饰器作用解析 #### 核心功能说明 1. **@Observed装饰器** 用于标记类或类的属性,当被装饰的类属性发生变化时,会触发UI更新。例如: ```typescript @Observed class UserInfo { name: string; age: number; } ``` 此时若`UserInfo`实例的`name`或`age`变化,会通知绑定了该对象的组件更新[^3]。 2. **@ObjectLink装饰器** 在**子组件**中使用,用于接收父组件传递的`@Observed`类实例,并与之建立**单向同步**(非双向绑定)。 ```typescript @Component struct ChildComponent { @ObjectLink user: UserInfo; // 仅接受父组件传递的@Observed实例 } ``` **关键限制**:子组件中禁止直接对`@ObjectLink`变量赋值(如`this.user = new UserInfo()`),否则会报错[^1][^2]。 #### 错误描述判断 以下为典型错误描述: **错误选项示例**: > "子组件中可以通过`@ObjectLink`直接修改对象引用,例如`this.user = new UserInfo()`" **错误原因**: 根据引用[1]引用[2],子组件中给`@ObjectLink`变量赋值属于明确禁止的操作,只能通过父组件更新数据源。 #### 对比其他装饰器 | 装饰器 | 作用场景 | 数据流向
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值