在鸿蒙Next中,@Observed和@ObjectLink是用于处理嵌套类对象属性变化、实现双向数据同步的装饰器。以下是对它们使用方法的详细说明:
一、@Observed装饰器功能特性:
- 用于标记类,使其创建的实例能被观察到属性变化。
- 主要用于嵌套类场景,弥补其他装饰器只能观察一层变化的局限。
使用方法:
- 定义类:在类定义前使用@Observed装饰器。@Observedclass MyClass { property: string; // 其他属性和方法}
- 创建实例:通过new关键字创建类的实例,该实例的属性变化将被观察。const myInstance = new MyClass();
注意事项:
- 如果类的属性是非简单类型(如class、Object或数组),这些属性也需要被@Observed装饰,否则其属性变化无法被观察到。
二、@ObjectLink装饰器功能特性:
- 用于装饰子组件中的状态变量,接收@Observed装饰的类的实例。
- 与父组件中对应的状态变量建立双向数据绑定。
使用方法:
- 在子组件中定义变量:使用@ObjectLink装饰器装饰变量,并指定类型为被@Observed装饰的类。@ObjectLink myObject: MyClass;
- 初始化变量:在子组件的构造函数或初始化方法中,从父组件接收@Observed装饰的类的实例。constructor(parentObject: MyClass) { this.myObject = parentObject;}
注意事项:
- @ObjectLink装饰的变量类型必须为被@Observed装饰的类实例,且必须指定类型。
- 该装饰器装饰的变量是只读的,不能被重新赋值(整体替换除外,但要在父组件进行)。
- 初始化时,同步源的class或数组必须是@State、@Link、@Provide、@Consume或者@ObjectLink装饰的数据。
三、使用场景示例嵌套对象:
@Observedclass BookName { size: number; // 其他属性和方法}@Observedclass Book { bookName: BookName; // 其他属性和方法}// 在父组件中@Stateuser: User = new User();// 在子组件中@ObjectLinkbookName: BookName;// 初始化constructor(parentBook: Book) { this.bookName = parentBook.bookName;}对象数组:
@Observedclass Info { info: string; // 其他属性和方法}// 在父组件中@Stateinfos: Info[] = [new Info(), new Info()];// 在子组件中@ObjectLinkinfo: Info;// 初始化constructor(parentInfo: Info) { this.info = parentInfo;}四、限制条件- @Observed装饰器会改变类的原始原型链,与其他类装饰器一起使用可能导致问题。
- @ObjectLink装饰器不能在@Entry装饰的自定义组件中使用。
- @ObjectLink装饰的变量不能本地初始化,只能通过构造参数从父组件传入初始值。
五、常见问题及注意事项- 赋值限制:在子组件中给@ObjectLink装饰的变量赋值是不允许的,会导致同步链打断和运行时报错。应在父组件进行整体替换或仅修改其属性。
- 嵌套对象属性观察:确保嵌套对象中的类及其属性(非简单类型)都被@Observed装饰,否则属性变化无法被观察到。
- UI刷新:当通过静态方法或组件内部方法修改@ObjectLink装饰的变量属性时,可能无法触发UI刷新。解决方法是先对变量进行赋值,使修改操作作用于带有Proxy代理的变量。