Harmony 状态管理神器 @ObservedV2

2025-06-24 22:03:42
108次阅读
0个评论

深入理解@ObservedV2装饰器:实现深度状态观测

什么是@ObservedV2装饰器?

@ObservedV2是HarmonyOS ArkUI框架中的一个类装饰器,用于增强状态管理框架对类对象中属性的观测能力。它需要与@Trace装饰器配合使用,使得被装饰的类和属性具有深度观测的能力,并能触发UI刷新。

核心特性

  1. 深度观测能力:@ObservedV2可以观测嵌套类对象属性的变化
  2. UI自动刷新:当被@Trace装饰的属性变化时,会通知关联的组件进行刷新
  3. API版本支持:从API version 12开始支持
  4. 必须配合使用:单独使用@ObservedV2或@Trace没有任何作用

基本用法

@ObservedV2
class Person {
  @Trace name: string = '';
  @Trace age: number = 0;
  
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

@Entry
@ComponentV2
struct Index {
  person: Person = new Person("张三", 25);
  
  build() {
    Column() {
      Text(`姓名: ${this.person.name}`)
      Text(`年龄: ${this.person.age}`)
      Button("增加年龄")
        .onClick(() => {
          this.person.age++; // 触发UI刷新
        })
    }
  }
}

嵌套类场景

@ObservedV2特别适合处理嵌套类结构的深度观测:

@ObservedV2
class Address {
  @Trace city: string = '';
  @Trace street: string = '';
}

@ObservedV2
class User {
  @Trace name: string = '';
  @Trace address: Address = new Address();
}

@Entry
@ComponentV2
struct UserProfile {
  user: User = new User();
  
  build() {
    Column() {
      Text(`用户: ${this.user.name}`)
      Text(`地址: ${this.user.address.city} ${this.user.address.street}`)
      Button("修改地址")
        .onClick(() => {
          this.user.address.city = "北京"; // 深度属性变化也能触发UI刷新
          this.user.address.street = "长安街";
        })
    }
  }
}

继承类场景

@ObservedV2也支持在继承类中使用:

@ObservedV2
class Animal {
  @Trace name: string = '';
}

class Dog extends Animal {
  @Trace breed: string = '';
}

@Entry
@ComponentV2
struct PetShop {
  dog: Dog = new Dog();
  
  build() {
    Column() {
      Text(`宠物名: ${this.dog.name}`)
      Text(`品种: ${this.dog.breed}`)
      Button("设置品种")
        .onClick(() => {
          this.dog.breed = "金毛"; // 触发UI刷新
        })
    }
  }
}

静态属性观测

@ObservedV2还可以观测静态属性的变化:

@ObservedV2
class Counter {
  @Trace static count: number = 0;
}

@Entry
@ComponentV2
struct StaticDemo {
  build() {
    Column() {
      Text(`计数: ${Counter.count}`)
      Button("增加计数")
        .onClick(() => {
          Counter.count++; // 静态属性变化也能触发UI刷新
        })
    }
  }
}

内置类型支持

@ObservedV2和@Trace支持多种内置类型的观测:

@ObservedV2
class CollectionDemo {
  @Trace numbers: number[] = [1, 2, 3];
  @Trace dataMap: Map<number, string> = new Map([[1, "a"], [2, "b"]]);
  @Trace dataSet: Set<number> = new Set([1, 2, 3]);
  @Trace importantDate: Date = new Date();
}

@Entry
@ComponentV2
struct CollectionExample {
  data: CollectionDemo = new CollectionDemo();
  
  build() {
    Column() {
      Button("修改数组")
        .onClick(() => {
          this.data.numbers.push(4); // 触发UI刷新
        })
      Button("修改Map")
        .onClick(() => {
          this.data.dataMap.set(3, "c"); // 触发UI刷新
        })
      Button("修改Date")
        .onClick(() => {
          this.data.importantDate.setFullYear(2023); // 触发UI刷新
        })
    }
  }
}

使用限制

  1. 必须配合@Trace使用:单独使用@ObservedV2无效
  2. 不能与V1装饰器混用:不能与@Observed、@Track等V1装饰器混合使用
  3. 序列化限制:@ObservedV2的类实例不支持使用JSON.stringify进行序列化
  4. 必须实例化:需要通过new操作符实例化后才具备被观测变化的能力

最佳实践

  1. 对于复杂嵌套数据结构,优先使用@ObservedV2和@Trace
  2. 简单数据类型可以直接使用@Local等装饰器
  3. 合理设计数据结构,避免过度嵌套
  4. 注意性能优化,避免不必要的深度观测

总结

@ObservedV2装饰器是ArkUI状态管理V2中的核心能力之一,它解决了嵌套类对象属性变化的观测问题,使得开发者能够更轻松地管理复杂应用状态。通过与@Trace的配合使用,可以实现深度属性变化的自动观测和UI刷新,大大提升了开发效率和代码可维护性。

收藏00

登录 后评论。没有帐号? 注册 一个。