鸿蒙应用入门级开发者认证实验二(状态管理和数据同步高级)

举报
黄生 发表于 2025/12/16 18:23:02 2025/12/16
【摘要】 @State和@Provide虽然都是状态管理装饰器,但设计目的是解决不同场景的问题。@State:仅作用于当前组件内部的状态管理,解决组件内私有状态的响应式更新。修改时仅触发当前组件刷新(框架会合并多次更新,避免性能问题)。示例:一个按钮的点击状态,仅影响当前组件的 UI 刷新。@Provide:用于跨组件层级共享状态(配合@Consume使用),解决跨层级状态共享的复杂性。替代传统的逐层...

@State@Provide虽然都是状态管理装饰器,但设计目的是解决不同场景的问题。

  • @State:仅作用于当前组件内部的状态管理,解决组件内私有状态的响应式更新。修改时仅触发当前组件刷新(框架会合并多次更新,避免性能问题)。示例:一个按钮的点击状态,仅影响当前组件的 UI 刷新。
  • @Provide:用于跨组件层级共享状态(配合@Consume使用),解决跨层级状态共享的复杂性。替代传统的逐层传递参数(Prop Drilling),简化深层嵌套组件的状态同步。示例:父组件的主题色状态,可被所有子组件自动同步更新。
特性 @State @Provide
作用域 组件内部 跨组件层级
更新范围 仅当前组件 所有关联的@Consume组件
设计目标 私有状态管理 状态共享与广播
性能影响 局部更新(高效) 按需更新(避免全局刷新)

reviewVote 是用于父子组件间状态同步的变量名,通常表示投票数或类似数值状态。

@Link 用于整体对象同步(如整个User对象),当父组件状态变化时,子组件会完全重建。若只需同步对象中的部分属性(如User.address),直接使用@Link会导致不必要的渲染开销。

@ObjectLink配合@Observed装饰类,实现对象内部属性级同步。子组件仅订阅特定嵌套对象的变化,避免整体刷新,极大提升性能。

1. 基础定义
import { Observed, ObjectLink } from '@kit.ArkUI';

// 用@Observed标记需监听的类
@Observed
class Address {
  city: string = 'Beijing';
  street: string = 'Chang\'an Street';
}

class User {
  name: string;
  address: Address; // 嵌套对象

  constructor(name: string, address: Address) {
    this.name = name;
    this.address = address;
  }
}
2. 父组件结构
@Component
struct ParentComponent {
  @State user: User = new User('Alice', new Address());

  build() {
    Column() {
      // 仅传递address对象(非整体user)
      ChildComponent({ address: this.user.address })
    }
  }
}
3. 子组件实现
@Component
struct ChildComponent {
  // 绑定嵌套对象
  @ObjectLink address: Address; 

  build() {
    Column() {
      Text(`City: ${this.address.city}`)
      Button('修改街道')
        .onClick(() => {
          // 直接修改属性,触发精准更新
          this.address.street = '新街道';
        })
    }
  }
}
  1. 精准更新 仅当Address对象的属性变化时触发子组件更新,父组件中User.name变化不会影响子组件。
  2. 深度监听 @Observed自动为类属性生成ObservableProperty,实现对嵌套对象的递归监听。
  3. **双向绑定 **子组件对@ObjectLink变量的修改会同步回父组件源数据。

注意:

  1. 必须配合@Observed 未标记@Observed的类无法触发@ObjectLink更新。

  2. 禁止整体替换 以下操作会破坏响应式

    // 错误!需操作属性而非替换对象
    this.address = new Address(); 
    

    正确做法:

    // 保持对象引用,仅修改属性
    this.address.city = 'Shanghai'; 
    
  3. 适用场景

    数据同步需求
    是否整体对象?
    @Link
    是否类对象属性?
    @ObjectLink + @Observed
    @Prop

当处理深层嵌套对象(如user.contact.address.location)时:

  1. 为每层嵌套类添加@Observed

  2. 每层组件使用@ObjectLink接收直接父层对象

  3. 避免超过3层的深度嵌套

    最佳实践:此模式在表单编辑、配置模块等需要局部更新的场景中性能提升显著,实测可减少50%+无效渲染。

@Observed是类装饰器,用于使嵌套对象(如对象的属性是对象)的属性变化可被观察,支持深层数据同步。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。