深入ArkTS:应用状态管理与LocalStorage装饰器详解【鸿蒙专栏-11】

举报
柠檬味拥抱 发表于 2023/11/30 00:13:33 2023/11/30
【摘要】 @[toc] ArkTS 应用状态管理详解在 ArkTS 中,实现应用级别的状态数据共享涉及到应用状态管理的概念。在前面的章节中,我们了解到页面级别的状态存储通过 LocalStorage 实现,而应用级别的状态管理则需要使用不同的工具。ArkTS 提供了多种应用状态管理的能力,包括 LocalStorage、AppStorage、PersistentStorage 以及 Environme...

@[toc]

ArkTS 应用状态管理详解

在 ArkTS 中,实现应用级别的状态数据共享涉及到应用状态管理的概念。在前面的章节中,我们了解到页面级别的状态存储通过 LocalStorage 实现,而应用级别的状态管理则需要使用不同的工具。ArkTS 提供了多种应用状态管理的能力,包括 LocalStorage、AppStorage、PersistentStorage 以及 Environment。让我们深入探讨这些功能并了解如何在应用中灵活运用。

LocalStorage: 页面级 UI 状态存储

LocalStorage 是用于页面级别的 UI 状态存储,通常用于在 UIAbility 内和页面之间进行状态共享。每个页面可以创建多个 LocalStorage 实例,这些实例可以在页面内共享,也可以在不同页面之间通过 GetShared 接口实现共享。
在这里插入图片描述

使用规则概述:

  1. 根组件使用 @Entry 装饰器分配一个 LocalStorage 实例,该实例将被组件树上的所有子组件自动访问。
  2. @Component 装饰的组件最多可以访问一个 LocalStorage 实例和 AppStorage,未被 @Entry 装饰的组件不可独立分配 LocalStorage 实例。
  3. LocalStorage 中的所有属性都是可变的,但是 LocalStorage 对象的生命周期由应用程序决定。
  4. 当应用释放最后一个指向 LocalStorage 的引用时,比如销毁最后一个自定义组件,LocalStorage 将被 JavaScript 引擎垃圾回收。

装饰器详解:

  • @LocalStorageProp: 建立单向同步关系,本地的修改不会同步回 LocalStorage 中对应属性。
  • @LocalStorageLink: 建立双向同步关系,本地的修改会同步回 LocalStorage 中对应属性,反之亦然。

限制条件:

  1. LocalStorage 创建后,命名属性的类型不可更改,后续调用 Set 时必须使用相同类型的值。
  2. 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 的状态管理提供了有益的信息。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。