深入ArkTS:应用状态管理与LocalStorage装饰器详解【鸿蒙专栏-11】
@[toc]
ArkTS 应用状态管理详解
在 ArkTS 中,实现应用级别的状态数据共享涉及到应用状态管理的概念。在前面的章节中,我们了解到页面级别的状态存储通过 LocalStorage 实现,而应用级别的状态管理则需要使用不同的工具。ArkTS 提供了多种应用状态管理的能力,包括 LocalStorage、AppStorage、PersistentStorage 以及 Environment。让我们深入探讨这些功能并了解如何在应用中灵活运用。
LocalStorage: 页面级 UI 状态存储
LocalStorage 是用于页面级别的 UI 状态存储,通常用于在 UIAbility 内和页面之间进行状态共享。每个页面可以创建多个 LocalStorage 实例,这些实例可以在页面内共享,也可以在不同页面之间通过 GetShared 接口实现共享。
使用规则概述:
- 根组件使用
@Entry
装饰器分配一个 LocalStorage 实例,该实例将被组件树上的所有子组件自动访问。 - 被
@Component
装饰的组件最多可以访问一个 LocalStorage 实例和 AppStorage,未被@Entry
装饰的组件不可独立分配 LocalStorage 实例。 - LocalStorage 中的所有属性都是可变的,但是 LocalStorage 对象的生命周期由应用程序决定。
- 当应用释放最后一个指向 LocalStorage 的引用时,比如销毁最后一个自定义组件,LocalStorage 将被 JavaScript 引擎垃圾回收。
装饰器详解:
@LocalStorageProp
: 建立单向同步关系,本地的修改不会同步回 LocalStorage 中对应属性。@LocalStorageLink
: 建立双向同步关系,本地的修改会同步回 LocalStorage 中对应属性,反之亦然。
限制条件:
- LocalStorage 创建后,命名属性的类型不可更改,后续调用 Set 时必须使用相同类型的值。
- LocalStorage 是页面级存储,GetShared 接口仅能获取当前 Stage 通过 windowStage.loadContent 传入的 LocalStorage 实例。
使用场景:
1. 应用逻辑使用 LocalStorage
let storage = new LocalStorage({ 'PropA': 47 });
let propA = storage.get('PropA'); // propA == 47
let link1 = storage.link('PropA'); // link1.get() == 47
let link2 = storage.link('PropA'); // link2.get() == 47
let prop = storage.prop('PropA'); // prop.get() = 47
link1.set(48); // two-way sync: link1.get() == link2.get() == prop.get() == 48
prop.set(1); // one-way sync: prop.get()=1; but link1.get() == link2.get() == 48
link1.set(49); // two-way sync: link1.get() == link2.get() == prop.get() == 49
2. 从 UI 内部使用 LocalStorage
let storage = new LocalStorage({ 'PropA': 47 });
@Entry(storage)
@Component
struct CompA {
@LocalStorageLink('PropA') storLink1: number = 1;
build() {
Column({ space: 15 }) {
Button(`Parent from LocalStorage ${this.storLink1}`)
.onClick(() => this.storLink1 += 1)
Child()
}
}
}
@Component
struct Child {
@LocalStorageLink('PropA') storLink2: number = 2;
build() {
Column({ space: 15 }) {
Text(`Parent from LocalStorage ${this.storLink2}`)
}
}
}
在上述示例中,我们演示了如何在应用逻辑中使用 LocalStorage,以及在 UI 内部如何通过 @LocalStorageLink
实现状态的同步。
ArkTS 应用状态管理进阶
在前文中,我们已经介绍了 ArkTS 中的 LocalStorage,并深入了解了它在页面级别的 UI 状态存储中的应用。接下来,我们将进一步探讨 LocalStorage 的使用场景和两个关键的装饰器 @LocalStorageProp
和 @LocalStorageLink
,以及它们的具体应用规则。
LocalStorage 装饰器详解
1. @LocalStorageProp
@LocalStorageProp
用于建立组件内部变量与 LocalStorage 中指定属性的单向同步关系。下面是该装饰器的使用规则:
- 装饰器参数:
key
,常量字符串,用于标识 LocalStorage 中的属性。 - 允许装饰的变量类型:Object、class、string、number、boolean、enum 类型以及这些类型的数组。
- 同步类型:单向同步,从 LocalStorage 的对应属性到组件的状态变量。
- 初始值:必须指定,如果 LocalStorage 实例中不存在属性,则作为初始化默认值,并存入 LocalStorage 中。
使用示例:
@Component
struct ExampleComponent {
@LocalStorageProp('exampleKey') exampleProp: number = 42;
build() {
Text(`Value from LocalStorage: ${this.exampleProp}`)
}
}
2. @LocalStorageLink
@LocalStorageLink
用于建立组件内部变量与 LocalStorage 中指定属性的双向同步关系。具体规则如下:
- 装饰器参数:
key
,常量字符串,用于标识 LocalStorage 中的属性。 - 允许装饰的变量类型:Object、class、string、number、boolean、enum 类型以及这些类型的数组。
- 同步类型:双向同步,从 LocalStorage 的对应属性到组件,从组件到 LocalStorage 对应属性。
- 初始值:必须指定,如果 LocalStorage 实例中不存在属性,则作为初始化默认值,并存入 LocalStorage 中。
使用示例:
@Component
struct ExampleComponent {
@LocalStorageLink('exampleKey') exampleLink: number = 42;
build() {
Text(`Value synced with LocalStorage: ${this.exampleLink}`)
}
}
观察变化和行为表现
无论是使用 @LocalStorageProp
还是 @LocalStorageLink
,我们可以观察到以下变化:
- 当装饰的数据类型为 boolean、string、number 时,可以观察到数值的变化。
- 当装饰的数据类型为 class 或 Object 时,可以观察到赋值和属性赋值的变化。
- 当装饰的对象是数组时,可以观察到数组的添加、删除、更新单元的变化。
框架行为方面,有一些重要的注意事项:
- 对于
@LocalStorageProp
,本地的修改永远不会同步回 LocalStorage 中,相反,如果 LocalStorage 中给定 key 的属性发生改变,改变会被同步给@LocalStorageProp
,并覆盖掉本地的修改。 - 对于
@LocalStorageLink
,本地的修改会同步回 LocalStorage 对应属性键值key
的属性中。
使用场景展示
1. 应用逻辑使用 @LocalStorageProp 和 @LocalStorageLink
let storage = new LocalStorage({ 'PropA': 47 });
// 应用逻辑中使用 LocalStorage
let propA = storage.get('PropA'); // propA == 47
let link1 = storage.link('PropA'); // link1.get() == 47
let link2 = storage.link('PropA'); // link2.get() == 47
let prop = storage.prop('PropA'); // prop.get() = 47
link1.set(48); // two-way sync: link1.get() == link2.get() == prop.get() == 48
prop.set(1); // one-way sync: prop.get()=1; but link1.get() == link2.get() == 48
link1.set(49); // two-way sync: link1.get() == link2.get() == prop.get() == 49
2. 从 UI 内部使用 LocalStorage
let storage = new LocalStorage({ 'PropA': 47 });
@Entry(storage)
@Component
struct CompA {
@LocalStorageLink('PropA') storLink1: number = 1;
build() {
Column({ space: 15 }) {
Button(`Parent from LocalStorage ${this.storLink1}`)
.onClick(() => this.storLink1 += 1)
Child()
}
}
}
@Component
struct Child {
@LocalStorageLink('PropA') storLink2: number = 2;
build() {
Column({ space: 15 }) {
Text(`Parent from LocalStorage ${this.storLink2}`)
}
}
}
3. @LocalStorageProp 和 LocalStorage 单向同步的简单场景
let storage = new LocalStorage({ 'PropA': 47 });
@Entry(storage)
@Component
struct CompA {
@LocalStorageProp('PropA') storProp1: number = 1;
build() {
Column({ space: 15 }) {
Button(`Parent from LocalStorage ${this.storProp1}`)
.onClick(() => this.storProp1 += 1)
Child()
}
}
}
@Component
struct Child {
@LocalStorageProp('PropA') storProp2: number = 2;
build() {
Column({ space: 15 }) {
Text(`Parent from LocalStorage ${this.storProp2}`)
}
}
}
4. @LocalStorageLink 和 LocalStorage 双向同步的简单场景
let storage = new LocalStorage({ 'PropA': 47 });
@Entry(storage)
@Component
struct CompA {
@LocalStorageLink('PropA') storLink: number = 1;
build() {
Column() {
Text(`incr @LocalStorageLink variable`)
.onClick(() => this.storLink += 1)
Text(`@LocalStorageLink: ${this.storLink}`)
}
}
}
5. 兄弟节点之间同步状态变量
let storage = new LocalStorage({ countStorage: 1 });
@Component
struct Child
A {
@LocalStorageLink('countStorage') countLink: number = 1;
build() {
Column({ space: 15 }) {
Text(`Count from LocalStorage: ${this.countLink}`)
}
}
}
@Component
struct ChildB {
@LocalStorageLink('countStorage') countLink: number = 1;
build() {
Column({ space: 15 }) {
Text(`Count from LocalStorage: ${this.countLink}`)
}
}
}
在上述示例中,我们展示了如何在不同的场景中使用 @LocalStorageProp
和 @LocalStorageLink
装饰器,以及它们在不同情境下的行为表现。这些装饰器为 ArkTS 中的状态管理提供了灵活且强大的工具,使开发者能够更好地处理页面和应用级别的状态。在实际应用中,根据需求选择合适的装饰器可以帮助提高代码的可读性和可维护性。
结语
通过 ArkTS 提供的 LocalStorage,我们可以方便地实现页面级别和应用级别的状态管理。在开发应用时,根据具体场景选择合适的状态管理方式,以提高应用的可维护性和灵活性。在未来的版本中,ArkTS 可能会进一步丰富状态管理的功能,开发者也应该关注文档的更新,以获取最新的开发信息。希望这篇博客对你理解 ArkTS 的状态管理提供了有益的信息。
- 点赞
- 收藏
- 关注作者
评论(0)