一、AppStorage概述
AppStorage是应用全局的UI状态存储,与应用进程绑定,在应用启动时由UI框架创建,为应用程序UI状态属性提供中央存储。它不同于页面级的LocalStorage,是应用级的全局状态共享,相当于整个应用的“中枢”,持久化数据PersistentStorage和环境变量Environment都通过它中转才能与UI交互。
(一)特点
- 应用启动时创建单例,提供应用状态数据的中心存储,运行过程中保留属性,通过唯一键字符串值访问。
- 支持与UI组件同步,可在应用业务逻辑中访问。
- 支持应用主线程内多个UIAbility实例间的状态共享。
- 其中属性可双向同步,数据可存于本地或远程设备,功能多样(如数据持久化),与UI解耦,需借助@StorageProp和@StorageLink在UI中使用相关数据。
二、@StorageProp用法
(一)装饰器使用规则
-
参数要求
-
key
:常量字符串,必填(需带引号)。
-
-
允许装饰的变量类型
- Object、class、string、number、boolean、enum类型及其数组。API12及以上支持Map、Set、Date类型及这些支持类型的联合类型(如string | number等)。不支持any,API12及以上支持undefined和null类型(使用时建议显式指定类型)。
-
同步类型
- 单向同步:从AppStorage对应属性到组件状态变量。允许本地改变,但本地修改不会同步回AppStorage,AppStorage属性改变会覆盖本地修改。
-
初始值要求
- 被装饰变量初始值必须指定,若AppStorage实例中不存在对应属性,则用初始值初始化该属性并存入AppStorage。
(二)变量的传递/访问规则
- 传递/访问说明
-
观察变化
- 装饰不同数据类型时可观察到不同变化:
- boolean、string、number类型:数值变化。
- class或Object类型:对象整体赋值和对象属性变化。
- array类型:数组添加、删除、更新数组单元的变化。
- Date类型:Date整体赋值及通过相关接口更新属性的变化。
- Map类型:Map整体赋值及通过相关接口更新值的变化。
- Set类型:Set整体赋值及通过相关接口更新值的变化。
- 装饰不同数据类型时可观察到不同变化:
-
框架行为
- 当@StorageProp(key)装饰的数值改变,修改不会同步回AppStorage对应属性。当前组件私有成员变量改变,其他绑定该key的数据不同步改变。若装饰的数据本身是状态变量,改变虽不回传AppStorage,但会引起所属自定义组件重新渲染。当AppStorage中key对应的属性改变,会同步给所有@StorageProp(key)装饰的数据并覆盖本地修改。
三、@StorageLink用法
(一)装饰器使用规则
-
参数要求
-
key
:常量字符串,必填(需带引号)。
-
-
允许装饰的变量类型
- 同@StorageProp,包括Object、class、string、number、boolean、enum类型及其数组,API12及以上支持Map、Set、Date类型及联合类型,不支持any,API12及以上支持undefined和null类型(使用时建议显式指定类型)。
-
同步类型
- 双向同步:从AppStorage对应属性到自定义组件,从自定义组件到AppStorage对应属性。
-
初始值要求
- 被装饰变量初始值必须指定,若AppStorage实例中不存在对应属性,则用初始值初始化该属性并存入AppStorage。
(二)变量的传递/访问规则
- 传递/访问说明
-
观察变化
- 与@StorageProp类似,装饰不同数据类型时可观察到相应变化(如boolean、string、number类型数值变化等)。
-
框架行为
- 当@StorageLink(key)装饰的数值改变,修改将同步回AppStorage对应属性。AppStorage中属性键值key对应的数据改变,绑定的所有数据(包括双向@StorageLink和单向@StorageProp)都同步修改。若装饰的数据本身是状态变量,改变会同步回AppStorage并引起所属自定义组件重新渲染。
四、限制条件
- @StorageProp/@StorageLink的参数必须为string类型,否则编译期报错。
- 不支持装饰Function类型变量,否则框架抛出运行时错误。
- 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
(二)从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)