HarmonyOS鸿蒙Next中嵌套数据的更新问题

HarmonyOS鸿蒙Next中嵌套数据的更新问题 鸿蒙开发最新版本,对于嵌套数据的更新有没有更好的解决方法?

3 回复

【解决方案】

  • 状态管理V1中要想观察大于一层的对象的属性变化可以使用@Observed/@ObjectLink,需要通过@Observed装饰目标对象,@ObjectLink接收目标对象实例。从下面demo可以看出,@State修饰的Bag对象因为只能观察第一层,导致this.bag.book.name不会刷新;而@ObjectLink修饰的Book对象可以观察到this.book.name的变化。代码如下所示:
@Observed
class Book {
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

@Observed
class Bag {
  book: Book;

  constructor(book: Book) {
    this.book = book;
  }
}

@Component
struct BookCard {
  [@ObjectLink](/user/ObjectLink) book: Book;

  build() {
    Column() {
      // 2.由于book是[@ObjectLink](/user/ObjectLink)修饰,可以观察到this.book.name的变化
      Text(`BookCard: ${this.book.name}`)
        .width(320)
        .margin(10)
        .textAlign(TextAlign.Center)

      Button('change book.name')
        .width(320)
        .margin(10)
        .onClick(() => {
          this.book.name = 'C++';
        })
    }
  }
}

@Entry
@Component
struct StateDemo001 {
  [@State](/user/State) bag: Bag = new Bag(new Book('JS00'));

  build() {
    Column() {
      // 1.由于当前bag对象是通过[@State](/user/State)修饰,无法观察到this.bag.book.name的变化
      Text(`Index: ${this.bag.book.name}`)
        .width(320)
        .margin(10)
        .textAlign(TextAlign.Center)

      Button('change bag.book.name')
        .width(320)
        .margin(10)
        .onClick(() => {
          this.bag.book.name = 'TS';
        })
      BookCard({ book: this.bag.book })
    }
  }
}

参考文档:[@ObservedV2装饰器和@Trace装饰器:类属性变化观测](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace)、[@Monitor装饰器:状态变量修改监听](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-monitor)。

@ObservedV2
class Info {
  [@Trace](/user/Trace) name: string = "Tom";
  [@Trace](/user/Trace) region: string = "North";
  [@Trace](/user/Trace) job: string = "Teacher";
  age: number = 25;

  // name被[@Trace](/user/Trace)装饰,能够监听变化
  [@Monitor](/user/Monitor)("name")
  onNameChange(monitor: IMonitor) {
    console.info(`name change from ${monitor.value()?.before} to ${monitor.value()?.now}`);
  }

  // age未被[@Trace](/user/Trace)装饰,不能监听变化
  [@Monitor](/user/Monitor)("age")
  onAgeChange(monitor: IMonitor) {
    console.info(`age change from ${monitor.value()?.before} to ${monitor.value()?.now}`);
  }

  // region与job均被[@Trace](/user/Trace)装饰,能够监听变化
  [@Monitor](/user/Monitor)("region", "job")
  onChange(monitor: IMonitor) {
    monitor.dirty.forEach((path: string) => {
      console.info(`${path} change from ${monitor.value(path)?.before} to ${monitor.value(path)?.now}`);
    })
  }
}

@Entry
@ComponentV2
struct Index {
  info: Info = new Info();

  build() {
    Column() {
      Button("change name")
        .onClick(() => {
          this.info.name = "Jack"; // 能够触发onNameChange方法
        })
      Button("change age")
        .onClick(() => {
          this.info.age = 26; // 不能够触发onAgeChange方法
        })
      Button("change region")
        .onClick(() => {
          this.info.region = "South"; // 能够触发onChange方法
        })
      Button("change job")
        .onClick(() => {
          this.info.job = "Driver"; // 能够触发onChange方法
        })
    }
  }
}

更多关于HarmonyOS鸿蒙Next中嵌套数据的更新问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,嵌套数据更新需使用状态管理机制。通过@State装饰器声明嵌套对象,结合@Observed@ObjectLink装饰器实现子组件数据同步更新。当嵌套数据属性变更时,框架会自动触发UI重新渲染。对于数组嵌套数据,需使用@State配合数组更新方法,确保框架能正确识别数据变化。ArkUI采用声明式UI范式,数据变更通过状态驱动视图更新,无需手动操作DOM。

在HarmonyOS Next中处理嵌套数据更新时,推荐使用状态管理库如@ohos/data或结合@State/@Provide等装饰器实现响应式更新。对于深层嵌套结构,建议:

  1. 使用@Observed@ObjectLink装饰器监听对象内部属性变化
  2. 采用不可变数据模式,通过展开运算符或immer.js生成新对象触发更新
  3. 复杂场景可使用MVVM模式配合ArkTS的Watch监听器实现精确更新

通过合理设计数据结构和更新策略,能有效解决嵌套数据的渲染性能问题。

回到顶部