鸿蒙 @Observed和@ObjectLink装饰器解析

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、核心概念与设计目的

1.1 设计背景

@Observed和@ObjectLink是ArkUI框架中专门用于处理嵌套对象属性变化的状态管理装饰器组合。它们解决了传统状态管理在复杂对象结构中的局限性,特别是在多层嵌套对象属性变更时的UI同步问题。

1.2 核心功能定位

  • @Observed: 类装饰器,用于标记一个类为可观察类,使其具备被观察的能力
  • @ObjectLink: 变量装饰器,用于建立与@Observed装饰的类实例的属性级双向绑定
  • 协同作用: 两者配合使用,实现对嵌套对象内部属性变化的精确监听和UI同步

二、版本支持与兼容性

版本支持情况
API version 9+支持在ArkTS卡片中使用
API version 11+支持在元服务中使用
未来版本持续增强对复杂数据类型的支持

三、装饰器详细说明

3.1 @Observed类装饰器

属性说明
装饰器参数
同步类型属性级双向同步
允许装饰的类型自定义类
不允许装饰的类型基本类型(string、number、boolean等)
初始值无需初始化

使用要求:

  • 必须装饰整个类,而不是类的某个属性
  • 类的属性变更需要通过赋值操作触发
  • 支持继承,子类会自动继承@Observed特性

3.2 @ObjectLink变量装饰器

属性说明
装饰器参数
同步类型属性级双向同步
允许装饰的变量类型@Observed装饰的类实例
不允许装饰的变量类型@Observed装饰的类实例
初始值必须从父组件初始化

初始化要求:

  • 必须从父组件初始化
  • 不支持本地初始化
  • 必须通过构造函数参数传递

绑定特性:

  • 建立与源对象的属性级绑定
  • 支持深层嵌套属性的同步
  • 避免不必要的深拷贝,提升性能

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

四、与相关装饰器的对比

4.1 与@Prop的对比

特性@ObjectLink@Prop
同步机制属性级双向同步单向同步
内存使用共享引用,内存占用低深拷贝,内存占用高
性能表现高性能,避免不必要的拷贝性能较差,需要深拷贝
嵌套支持支持深层嵌套,无层级限制建议不超过5层嵌套
适用场景需要修改嵌套对象属性只需要读取数据

4.2 与@State/@Link的对比

特性@ObjectLink@State/@Link
同步粒度属性级别对象级别
更新机制只更新变化的属性更新整个对象
性能优化精确更新,性能更优整体更新,可能造成不必要的渲染
使用复杂度需要配合@Observed使用直接使用

五、基础使用示例

// 定义被观察的类
@Observed
class User {
  name: string
  age: number
  address: Address

  constructor(name: string, age: number, address: Address) {
    this.name = name
    this.age = age
    this.address = address
  }
}

@Observed
class Address {
  city: string
  street: string

  constructor(city: string, street: string) {
    this.city = city
    this.street = street
  }
}

// 父组件
@Entry
@Component
struct Parent {
  @State user: User = new User('Alice', 25, new Address('Beijing', 'Main St'))

  build() {
    Column() {
      Text(`User: ${this.user.name}, ${this.user.age}`)
      Text(`Address: ${this.user.address.city}, ${this.user.address.street}`)
      Child({ user: this.user })
    }
  }
}

// 子组件
@Component
struct Child {
  @ObjectLink user: User

  build() {
    Column() {
      Button('Increase Age')
        .onClick(() => {
          this.user.age += 1 // 直接修改属性,会同步到父组件
        })
      Button('Change Address')
        .onClick(() => {
          this.user.address.city = 'Shanghai' // 嵌套属性修改也会同步
        })
    }
  }
}

六、观察变化机制

6.1 支持的变更类型

基本类型属性变更:

  • string、number、boolean值的直接赋值
  • enum值的变更

对象属性赋值:

  • 整个对象的重新赋值
  • 对象引用的变更

数组操作:

  • 数组项的赋值修改
  • push()、pop()、splice()等数组方法调用
  • 数组长度的变更

集合类型操作:

  • Map的set()、delete()、clear()操作
  • Set的add()、delete()、clear()操作

6.2 变更检测机制

属性访问器重写: @Observed会重写类的属性访问器,在属性被修改时触发通知机制

变更传播:

  • 属性变更 → 通知@ObjectLink装饰的变量 → 触发UI更新
  • 支持嵌套属性的变更传播

批量更新优化:

  • 在同一执行上下文中多次修改只会触发一次UI更新
  • 避免不必要的重复渲染
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值