鸿蒙状态管理概述

发布于:2025-02-20 ⋅ 阅读:(25) ⋅ 点赞:(0)

状态管理之v1

  • @State 管理组件内部状态
  • @Prop 用于父组件传递数据,子组件不能修改
  • @Link 实现双向绑定,子组件可以修改
  • @Provide 与 @Consume 则提供了全局共享状态的机制。
  • @Observed:声明可观察对象,
  • @ObjectLink:用于实现双向数据绑定,允许子组件直接修改父组件的对象,适合复杂对象的双向传递。
  • @LocalStorage: 页面级UI状态存储,装饰器有@LocalStorageProp和@LocalStorageLink
  • @AppStorage: 应用全局的UI状态存储,装饰器有@StorageProp和@StorageLink
  • @PersistentStorage: 持久化存储UI状态,需要依赖AppStorage
  • @Environment: 设备环境查询,需要依赖AppStorage
  • @Watch:状态变量更改通知
  • $$语法:内置组件双向同步
  • @Track:class对象属性级更新

@LocalStorage

  • 应用程序可以创建多个LocalStorage实例,LocalStorage实例可以在页面内共享,也可以通过getShared接口,实现跨页面、UIAbility实例内共享。
  • 组件树的根节点,即被@Entry装饰的@Component,可以被分配一个LocalStorage实例,此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限。
  • @Component装饰的组件既可以自动继承来自父组件的LocalStorage实例,也可以传入指定的LocalStorage的实例。
  • LocalStorage中的所有属性都是可变的。

LocalStorageLink的框架行为

  • 当@LocalStorageLink(key)装饰的数值改变被观察到时,修改将被同步回LocalStorage对应属性键值key的属性中。
  • LocalStorage中属性键值key对应的数据一旦改变,属性键值key绑定的所有的数据(包括双向@LocalStorageLink和单向@LocalStorageProp)都将同步修改。
  • 当@LocalStorageLink(key)装饰的数据本身是状态变量,它的改变不仅仅会同步回LocalStorage中,还会引起所属的自定义组件的重新渲染。

LocalStorageProp的框架行为

  • 被@LocalStorageProp装饰的变量的值的变化不会同步回LocalStorage里。
  • @LocalStorageProp装饰的变量变化会使当前自定义组件中关联的组件刷新。
  • LocalStorage(key)中值的变化会引发所有被@LocalStorageProp对应key装饰的变量的变化,会覆盖@LocalStorageProp本地的改变。

LocalStorage使用场景

  • 可以在应用逻辑使用LocalStorage
  • 可以从UI内部使用 或者 自定义组件外使用
  • 根结点可通过@Entry来接收 LocalStorage ,子节点可通过构造参数来传递 LocalStorage
  • 可以从UIAbility共享到一个或多个视图(关键api:windowStage.loadContentgetShared()
  • LocalStorageLink 的双向同步
  • LocalStorageProp 的单向同步

@AppStorage

  • AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。
  • AppStorage可以和UI组件同步,且可以在应用业务逻辑中被访问。
  • AppStorage支持应用的主线程内多个UIAbility实例间的状态共享。

StorageLink的框架行为

  • 当@StorageLink(key)装饰的数值改变被观察到时,修改将被同步回AppStorage对应属性键值key的属性中。
  • AppStorage中属性键值key对应的数据一旦改变,属性键值key绑定的所有的数据(包括双向@StorageLink和单向@StorageProp)都将同步修改。
  • 当@StorageLink(key)装饰的数据本身是状态变量,它的改变不仅仅会同步回AppStorage中,还会引起所属的自定义组件的重新渲染。

StorageProp的框架行为

  • 当@StorageProp(key)装饰的数值改变被观察到时,修改不会被同步回AppStorage对应key的属性中。
  • 当前@StorageProp(key)单向绑定的数据会被修改,即仅限于当前组件的私有成员变量改变,其他绑定该key的数据不会同步改变。
  • 当@StorageProp(key)装饰的数据本身是状态变量,它的改变虽然不会同步回AppStorage中,但是会引起所属的自定义组件重新渲染。
  • 当AppStorage中key对应的属性发生改变时,会同步给所有@StorageProp(key)装饰的数据,@StorageProp(key)本地的修改将被覆盖。

AppStorage的使用场景

  • 可以在应用逻辑使用AppStorage
  • 可以从UI内部使用 AppStorage
  • 应用的主线程内多个UIAbility实例间的状态共享
  • StorageProp 的单向同步
  • StorageLink 的双向同步

@PersistentStorage

  • PersistentStorage将选定的AppStorage属性保留在设备磁盘上。(关键api: PersistentStorage.persistProp('aProp', 47);)
  • UI和业务逻辑不直接访问PersistentStorage中的属性,所有属性访问都是对AppStorage的访问
  • PersistentStorage和AppStorage中的属性建立双向同步。

@Environment

  • 开发者如果需要应用程序运行的设备的环境参数,以此来作出不同的场景判断,比如多语言,深浅色模式等,需要用到Environment设备环境查询。
  • Environment是ArkUI框架在应用程序启动时创建的单例对象。它为AppStorage提供了一系列描述应用程序运行状态的属性。Environment的所有属性都是不可变的(即应用不可写入),所有的属性都是简单类型。
  • Environment提供了读取系统某些环境变量的能力,具体见Environment内置参数,并将其值写入AppStorage里,所以开发者需要通过AppStorage才能获取环境变量的值。
  • 关键api: Environment.envProp('languageCode', 'en');

Environment内置参数

数据类型 描述
accessibilityEnabled boolean 获取无障碍屏幕读取是否启用。
colorMode ColorMode 色彩模型类型:选项为ColorMode.LIGHT: 浅色,ColorMode.DARK: 深色。
fontScale number 字体大小比例。开发者需要配置configuration使fontScale跟随系统变化
fontWeightScale number 字体粗细程度。
layoutDirection LayoutDirection 布局方向类型:包括LayoutDirection.LTR: 从左到右,LayoutDirection.RTL: 从右到左。
languageCode string 当前系统语言值,取值必须为小写字母, 例如zh。

@Watch

  • @Watch提供了状态变量的监听能力,@Watch仅能监听到可以观察到的变化。
  • @Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数。
  • @Watch在ArkUI框架内部判断数值有无更新使用的是严格相等(===)

Watch的使用场景

  • 建议@State、@Prop、@Link等装饰器在@Watch装饰器之前,以保持整体风格的一致。
@State @Watch('change') num: number = 10;
change() {
  console.log(`xxx`);
}

$$语法

  • 为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。
  • 用于@Builder装饰器的按引用传递参数
  • $$支持基础类型变量,以及@State、@Link和@Prop装饰的变量。

$$ 使用场景

// xxx.ets
@Entry
@Component
struct TextInputExample {
  @State text: string = ''
  controller: TextInputController = new TextInputController()

  build() {
    Column({ space: 20 }) {
      Text(this.text)
      TextInput({ text: $$this.text, placeholder: 'input your word...', controller: this.controller })
        .placeholderColor(Color.Grey)
        .placeholderFont({ size: 14, weight: 400 })
        .caretColor(Color.Blue)
        .width(300)
    }.width('100%').height('100%').justifyContent(FlexAlign.Center)
  }
}

@Track

  • @Track应用于class对象的属性级更新。@Track装饰的属性变化时,只会触发该属性关联的UI更新。
  • @Track是class对象的属性装饰器。当一个class对象是状态变量时,@Track装饰的属性发生变化,只会触发该属性关联的UI更新
  • 如果class类中使用了@Track装饰器,则未被@Track装饰器装饰的属性不能在UI中使用,如果使用,会发生运行时报错。

参考资料:状态管理(V1)


网站公告

今日签到

点亮在社区的每一天
去签到