一、一句话总功能

  • @ObservedV2新一代观察类(推荐),标记一个类可被监听,属性变化自动刷新 UI。
  • @Trace标记属性可追踪,配合 @ObservedV2 使用,让属性变化能触发刷新。
  • @Observed老版观察类,功能同 @ObservedV2,但性能弱一些。
  • @ObjectLink子组件接收 观察对象,双向同步,父 ↔ 子 对象互通。

二、核心区别(最关键)

表格

装饰器 作用 版本 必须配合 使用场景
@ObservedV2 标记类可观察(新一代) 新版推荐 @Trace 自定义类、数据模型、业务对象
@Trace 标记类里哪些属性可监听 新版 @ObservedV2 类内部属性
@Observed 老版可观察类 旧版 无需配合 兼容老代码
@ObjectLink 子组件接收可观察对象 全版本 必须传 @Observed/@ObservedV2 对象 父子组件传递对象

三、逐一带你学 + 案例(可直接复制运行)

1)@ObservedV2 + @Trace(新一代官方推荐)

作用

  • class加上 @ObservedV2
  • 需要响应式的属性加上 @Trace→ 属性变化 → UI 自动刷新

完整案例

// 1. 定义可观察类
@ObservedV2
class User {
  @Trace name: string = ""; // 可追踪
  @Trace age: number = 0; // 可追踪
  address: string = ""; // 无@Trace → 变化不刷新UI
}

// 2. 页面使用
@Entry
@Component
struct Index {
  user: User = new User();

  build() {
    Column({ space: 20 }) {
      Text(`姓名:${this.user.name}`)
      Text(`年龄:${this.user.age}`)

      Button("修改姓名(触发刷新)")
        .onClick(() => {
          this.user.name = "鸿蒙开发"; // 变 → UI刷新
        });

      Button("修改年龄(触发刷新)")
        .onClick(() => {
          this.user.age = 25; // 变 → UI刷新
        });
    }
    .padding(30)
  }
}

2)@Observed(老版,不需要 @Trace)

作用

  • 老版可观察类
  • 整个类所有属性自动可观察,不用写 @Trace

案例

@Observed
class User {
  name: string = "张三";
  age: number = 20;
}

@Entry
@Component
struct Index {
  user: User = new User();

  build() {
    Column() {
      Text(`${this.user.name}`)
      Button("改名字").onClick(() => {
        this.user.name = "李四"; // 自动刷新
      })
    }
  }
}

3)@ObjectLink(子组件接收可观察对象)

作用

  • 父组件传一个被 @Observed/@ObservedV2 修饰的对象
  • 子组件用 @ObjectLink 接收
  • 父子对象双向同步,改任何一方都同步

注意

  • 不需要 @State
  • 不需要 @Link
  • 专门给对象用

完整父子案例(超级常用)

父组件
@ObservedV2
class User {
  @Trace name: string = "张三";
}

@Entry
@Component
struct Parent {
  user: User = new User();

  build() {
    Column({ space: 20 }) {
      Text(`父:${this.user.name}`)
      Child({ user: this.user }) // 传对象
    }
    .padding(30)
  }
}
子组件
@Component
struct Child {
  // 子组件接收可观察对象
  @ObjectLink user: User;

  build() {
    Column() {
      Text(`子:${this.user.name}`)
      Button("子组件修改名字")
        .onClick(() => {
          this.user.name = "子组件修改的";
          // 父组件也会同步!!!
        })
    }
  }
}

四、最核心总结(背会就能面试 + 写项目)

1. 什么时候用?

  • 你有一个class 对象,希望属性变化自动刷新页面→ 用 @ObservedV2 + @Trace

  • 你要在子组件使用这个对象→ 子组件用 @ObjectLink 接收

2. 新版固定写法(官方推荐)

@ObservedV2
class 类名 {
  @Trace 属性1;
  @Trace 属性2;
}

组件内:
直接用 = new 类名()

子组件:
@ObjectLink 对象: 类名;

3. 四者关系一句话

  • @ObservedV2 = 给类开监听
  • @Trace = 给属性开监听
  • @Observed = 老版全包监听
  • @ObjectLink = 子组件接收监听对象

五、我再给你一个项目标准模型写法(可写进简历)

// 音乐项目歌单模型(标准写法)
@ObservedV2
export class Playlist {
  @Trace id: number = 0;
  @Trace name: string = "";
  @Trace cover: string = "";
  @Trace playCount: number = 0;

  constructor(id: number, name: string, cover: string) {
    this.id = id;
    this.name = name;
    this.cover = cover;
  }
}

// 页面使用
@Entry
@Component
struct MusicPage {
  playlist: Playlist = new Playlist(1, "热门歌单", "xxx.jpg");

  build() {
    Column() {
      Text(this.playlist.name)
      PlaylistItem({ item: this.playlist })
    }
  }
}

// 子组件
@Component
struct PlaylistItem {
  @ObjectLink item: Playlist;

  build() {
    Text(this.item.name)
  }
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐