鸿蒙开发中是应用状态的管理

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

在鸿蒙(HarmonyOS)应用开发中,状态管理是构建复杂应用的核心机制。ArkTS 提供了多层次的状态管理方案,从组件内状态到跨组件/跨页面的全局状态共享,形成了一套完整的解决方案。

一、状态管理的核心概念

1. 状态(State)与UI的关系
  • 状态驱动UI:当状态变化时,框架自动触发UI更新(无需手动操作DOM)。
  • 单向数据流:数据从父组件流向子组件,保证可预测性。
2. 状态分类
类型 作用范围 典型场景
组件内状态 当前组件 按钮的选中状态
组件间状态 父子/兄弟组件 表单数据传递
全局状态 整个应用 用户登录信息、主题设置

二、基础状态管理:组件内状态

1. @State 装饰器
  • 特点:组件私有的可变状态,变化时触发该组件及其子组件的UI更新。
  • 示例:计数器
  @Component
  struct Counter {
    @State count: number = 0; // 定义状态

    build() {
      Column() {
        Text(`Count: ${this.count}`)
        Button('+1').onClick(() => this.count++) // 修改状态,自动更新UI
      }
    }
  }

注意@State 仅支持在组件内部修改。

2. @Prop 装饰器
  • 特点:从父组件单向接收数据,子组件不能直接修改(类似React的props)。
  • 示例:父子组件通信
  @Component
  struct Parent {
    @State message: string = 'Hello';

    build() {
      Column() {
        Child({ msg: this.message }) // 传递状态
        Button('Change').onClick(() => this.message = 'Updated')
      }
    }
  }

  @Component
  struct Child {
    @Prop msg: string; // 接收父组件数据

    build() {
      Text(this.msg) // 显示父组件传递的值
    }
  }
3. @Link 装饰器
  • 特点:建立父子组件的双向绑定,子组件可修改父组件状态。
  • 示例:双向同步
  @Component
  struct Parent {
    @State text: string = '';

    build() {
      Column() {
        TextInput({ text: this.$text }) // 双向绑定
        Text(`Parent: ${this.text}`)
      }
    }
  }

  @Component
  struct TextInput {
    @Link text: string; // 双向绑定

    build() {
      TextInput({ text: this.text })
        .onChange((val) => this.text = val) // 修改会同步到父组件
    }
  }

三、中级状态管理:组件间共享状态

1. @Provide 和 @Consume
  • 特点:跨层级组件共享状态(无需逐层传递)。
  • 示例:主题颜色共享
  @Component
  struct Root {
    @Provide theme: string = 'light'; // 提供状态

    build() {
      Column() {
        Button('Toggle Theme')
          .onClick(() => this.theme = this.theme === 'light' ? 'dark' : 'light')
        Child() // 任意层级的子组件均可消费
      }
    }
  }

  @Component
  struct Child {
    @Consume theme: string; // 消费状态

    build() {
      Text('Child').fontColor(this.theme === 'light' ? '#000' : '#FFF')
    }
  }
2. @Observed 和 @ObjectLink
  • 特点:用于嵌套对象的属性级更新(避免整个对象重新渲染)。
  • 示例:表单对象管理
  @Observed
  class User {
    name: string = '';
    age: number = 0;
  }

  @Component
  struct Form {
    @State user: User = new User();

    build() {
      Column() {
        Input({ value: this.user.name })
          .onChange((val) => this.user.name = val)
        Display({ user: this.user }) // 传递对象
      }
    }
  }

  @Component
  struct Display {
    @ObjectLink user: User; // 绑定对象属性

    build() {
      Text(`Name: ${this.user.name}`)
    }
  }

四、高级状态管理:全局状态

1. AppStorage:应用级全局状态
  • 特点:整个应用共享的状态存储,支持持久化。
  • 示例:用户登录信息
  // 存储状态
  AppStorage.SetOrCreate('isLogin', false);

  @Component
  struct LoginPage {
    @StorageLink('isLogin') isLogin: boolean; // 绑定全局状态

    build() {
      if (this.isLogin) {
        Text('Welcome')
      } else {
        Button('Login').onClick(() => this.isLogin = true)
      }
    }
  }
2. LocalStorage:页面级状态共享
  • 特点:单个页面内多个组件共享状态(生命周期与页面绑定)。
  • 示例:页面内组件通信
  let storage = new LocalStorage();

  @Component
  struct PageA {
    @LocalStorageLink('data') data: string = '';

    build() {
      Column() {
        TextInput({ text: this.data })
      }
    }
  }

  @Component
  struct PageB {
    @LocalStorageLink('data') data: string = '';

    build() {
      Text(this.data) // 与PageA共享数据
    }
  }

五、其他

1. 状态提升(Lifting State Up)
  • 将共享状态提升到最近的共同父组件,避免冗余同步。
2. 不可变数据(Immutable Data)
  • 使用展开运算符或@Observed类确保状态变更可追踪:
  @State user: User = { name: 'Alice', age: 25 };

  // 错误:直接修改不会触发更新
  this.user.name = 'Bob';

  // 正确:创建新对象
  this.user = { ...this.user, name: 'Bob' };
3. 性能优化
  • 细粒度更新:使用@ObjectLink减少渲染范围。
  • 状态隔离:将频繁更新的状态与静态状态分离。

六、状态管理方案对比

方案 作用范围 数据流 适用场景
@State 组件内部 内部可变 私有状态(如按钮点击)
@Prop 父→子组件 单向 组件通信(只读)
@Link 父子组件 双向 表单双向绑定
@Provide/@Consume 跨层级组件 多级共享 主题、语言切换
AppStorage 全局 任意组件 用户登录状态

你可能感兴趣的:(鸿蒙,harmonyos,华为,鸿蒙)