DEV Community

Freerain
Freerain

Posted on

鸿蒙Next应用全局状态AppStorage用法总结

一、AppStorage概述

AppStorage是应用全局的UI状态存储,与应用进程绑定,在应用启动时由UI框架创建,为应用程序UI状态属性提供中央存储。它不同于页面级的LocalStorage,是应用级的全局状态共享,相当于整个应用的“中枢”,持久化数据PersistentStorage和环境变量Environment都通过它中转才能与UI交互。

(一)特点

  1. 应用启动时创建单例,提供应用状态数据的中心存储,运行过程中保留属性,通过唯一键字符串值访问。
  2. 支持与UI组件同步,可在应用业务逻辑中访问。
  3. 支持应用主线程内多个UIAbility实例间的状态共享。
  4. 其中属性可双向同步,数据可存于本地或远程设备,功能多样(如数据持久化),与UI解耦,需借助@StorageProp和@StorageLink在UI中使用相关数据。

二、@StorageProp用法

(一)装饰器使用规则

  1. 参数要求
    • key:常量字符串,必填(需带引号)。
  2. 允许装饰的变量类型
    • Object、class、string、number、boolean、enum类型及其数组。API12及以上支持Map、Set、Date类型及这些支持类型的联合类型(如string | number等)。不支持any,API12及以上支持undefined和null类型(使用时建议显式指定类型)。
  3. 同步类型
    • 单向同步:从AppStorage对应属性到组件状态变量。允许本地改变,但本地修改不会同步回AppStorage,AppStorage属性改变会覆盖本地修改。
  4. 初始值要求
    • 被装饰变量初始值必须指定,若AppStorage实例中不存在对应属性,则用初始值初始化该属性并存入AppStorage。

(二)变量的传递/访问规则

  1. 传递/访问说明
    • 从父节点初始化和更新禁止,只能由AppStorage中key对应的属性初始化(若不存在则用本地默认值)。支持初始化子节点(可用于初始化@State、@link@prop、@Provide等)。不支持组件外访问。 ### (三)观察变化和行为表现
  2. 观察变化
    • 装饰不同数据类型时可观察到不同变化:
      • boolean、string、number类型:数值变化。
      • class或Object类型:对象整体赋值和对象属性变化。
      • array类型:数组添加、删除、更新数组单元的变化。
      • Date类型:Date整体赋值及通过相关接口更新属性的变化。
      • Map类型:Map整体赋值及通过相关接口更新值的变化。
      • Set类型:Set整体赋值及通过相关接口更新值的变化。
  3. 框架行为
    • 当@StorageProp(key)装饰的数值改变,修改不会同步回AppStorage对应属性。当前组件私有成员变量改变,其他绑定该key的数据不同步改变。若装饰的数据本身是状态变量,改变虽不回传AppStorage,但会引起所属自定义组件重新渲染。当AppStorage中key对应的属性改变,会同步给所有@StorageProp(key)装饰的数据并覆盖本地修改。

三、@StorageLink用法

(一)装饰器使用规则

  1. 参数要求
    • key:常量字符串,必填(需带引号)。
  2. 允许装饰的变量类型
    • 同@StorageProp,包括Object、class、string、number、boolean、enum类型及其数组,API12及以上支持Map、Set、Date类型及联合类型,不支持any,API12及以上支持undefined和null类型(使用时建议显式指定类型)。
  3. 同步类型
    • 双向同步:从AppStorage对应属性到自定义组件,从自定义组件到AppStorage对应属性。
  4. 初始值要求
    • 被装饰变量初始值必须指定,若AppStorage实例中不存在对应属性,则用初始值初始化该属性并存入AppStorage。

(二)变量的传递/访问规则

  1. 传递/访问说明
    • 从父节点初始化和更新禁止。支持初始化子节点(可用于初始化常规变量、@State、@link@prop、@Provide等)。不支持组件外访问。 ### (三)观察变化和行为表现
  2. 观察变化
    • 与@StorageProp类似,装饰不同数据类型时可观察到相应变化(如boolean、string、number类型数值变化等)。
  3. 框架行为
    • 当@StorageLink(key)装饰的数值改变,修改将同步回AppStorage对应属性。AppStorage中属性键值key对应的数据改变,绑定的所有数据(包括双向@StorageLink和单向@StorageProp)都同步修改。若装饰的数据本身是状态变量,改变会同步回AppStorage并引起所属自定义组件重新渲染。

四、限制条件

  1. @StorageProp/@StorageLink的参数必须为string类型,否则编译期报错。
  2. 不支持装饰Function类型变量,否则框架抛出运行时错误。
  3. AppStorage与PersistentStorage以及Environment配合使用时:
    • 在AppStorage中创建属性后调用PersistentStorage.persistProp()接口,会覆盖PersistentStorage同名属性,建议反序调用。
    • 在AppStorage中创建属性后再用Environment.envProp()创建同名属性会失败,AppStorage已有同名属性时,Environment环境变量不再写入,建议AppStorage属性不使用Environment预置环境变量名。
    • 若改变变量仅用于消息传递而非UI更新,推荐使用emitter方式而非@StorageLink双向同步机制(如不建议借助@StorageLink实现事件通知)。

五、使用场景

(一)从应用逻辑使用AppStorage和LocalStorage

AppStorage是单例,API静态,使用方法类似LocalStorage非静态方法。

AppStorage.setOrCreate('PropA',47);
let storage:LocalStorage = new LocalStorage();
storage.setOrCreate('PropA',17);
let propA:number|undefined = AppStorage.get('PropA'); // propA in AppStorage == 47, propA in LocalStorage == 17
let link1:SubscribedAbstractProperty<number> = AppStorage.link('PropA'); // link1.get() == 47
let link2:SubscribedAbstractProperty<number> = AppStorage.link('PropA'); // link2.get() == 47
let prop:SubscribedAbstractProperty<number> = AppStorage.prop('PropA'); // prop.get() == 47
link1.set(48); // 双向同步: link1.get() == link2.get() == prop.get() == 48
prop.set(1); // 单向同步: prop.get() == 1; 但 link1.get() == link2.get() == 48
link1.set(49); // 双向同步: link1.get() == link2.get() == prop.get() == 49
storage.get<number> ('PropA') // == 17
storage.set('PropA',101);
storage.get<number> ('PropA') // == 101
AppStorage.get<number> ('PropA') // == 49
link1.get() // == 49
link2.get() // == 49
prop.get() // == 49
Enter fullscreen mode Exit fullscreen mode

(二)从UI内部使用AppStorage和LocalStorage

在 UI 内部使用 AppStorage 和 LocalStorage 时,主要通过@StorageLink变量装饰器与 AppStorage 配合来实现双向数据同步。例如,在自定义组件中使用@StorageLink装饰变量,使其与 AppStorage 中的属性建立关联。当组件中的该变量发生变化时,变化会同步到 AppStorage 中相应属性;反之,当 AppStorage 中对应属性改变时,组件中的变量也会随之更新,从而实现 UI 与应用全局状态的实时同步。这种机制确保了在 UI 界面操作时,相关数据能够及时在整个应用范围内保持一致,提升了用户体验和数据的一致性管理。同时,在处理 UI 相关逻辑时,开发者可以更方便地利用 AppStorage 作为数据中心,集中管理和操作 UI 状态数据,减少了数据传递和同步的复杂性,提高了开发效率和代码的可维护性。与@LocalStorageLink和 LocalStorage 的配合使用类似,@StorageLink为应用级的 UI 状态管理提供了便捷的双向数据同步方式,使得 UI 组件能够更好地响应应用状态的变化,并且能够及时将 UI 操作反馈到应用全局状态中。

Top comments (0)