掌握HarmonyOS框架的ArkTs如何管理和共享状态数据

本文分享自华为云社区《深入理解ArkTs中的AppStorage和LocalStorage》,作者:柠檬味拥抱 。

ARKTS(Ark TypeScript)是HarmonyOS应用框架的一部分,提供了一种灵活而强大的状态管理机制。在ARKTS中,AppStorage和LocalStorage是两个关键的概念,它们分别用于应用级和页面级的状态共享。通过深入了解这两个特性,我们可以更好地理解如何在应用程序中管理和共享状态数据。

AppStorage:全局状态的中枢

AppStorage是应用启动时创建的单例,其主要目的是提供应用级别的全局状态存储。这些状态数据在整个应用中都是可访问的,它们在应用运行期间保留其属性。通过唯一的键字符串,我们可以访问AppStorage中的属性,实现全局状态的共享。

与UI的交互是通过@StorageProp和@StorageLink实现的。@StorageProp用于建立单向数据同步,允许本地的修改发生,但不会同步回AppStorage中。而@StorageLink建立双向数据同步,使得本地的修改会被同步到AppStorage中,反之亦然。这为应用的状态管理提供了极大的灵活性。

复制代码
// 示例代码

@StorageProp('exampleKey')

exampleValue: number = 42;

@StorageLink('anotherKey')

anotherValue: string = 'Hello, ARKTS!';

通过上述代码,我们在AppStorage中创建了两个属性:'exampleKey'和'anotherKey',并通过@StorageProp和@StorageLink将它们与UI组件中的变量建立了关联。这种关联使得应用状态和UI的变化能够实时同步,实现了高效的状态管理。

LocalStorage:页面级的数据共享

与AppStorage不同,LocalStorage是页面级的数据共享机制。通常应用于页面内的数据共享,它提供了一种简单而有效的方式,使页面组件能够共享状态而不需要显式的传递数据。在页面级别,LocalStorage的作用类似于组件内部的全局变量,方便在页面内各个组件之间进行状态传递。

复制代码
// 示例代码

let pageStorage: LocalStorage = new LocalStorage();

pageStorage.set('pageTitle', 'My Awesome Page');

let title: string = pageStorage.get('pageTitle');

在上述代码中,我们使用LocalStorage创建了一个页面级的存储空间,并在其中存储了页面的标题。通过get和set方法,我们能够在页面内的任何组件中访问和修改这些数据,实现了页面级别的状态共享。

与PersistentStorage和Environment的协作

AppStorage不仅可以和UI组件同步,还可以与PersistentStorage(持久化数据存储)和Environment(环境变量)协作,形成一个完整的状态管理体系。通过持久化数据的存储和环境变量的设置,我们能够实现数据的长期保存和应用环境的灵活配置。

需要注意的是,使用AppStorage与PersistentStorage时,需要注意调用顺序。在AppStorage中创建属性后,调用PersistentStorage.persistProp()时会使用AppStorage中已经存在的值,并覆盖PersistentStorage中的同名属性。因此,建议在使用PersistentStorage前访问AppStorage中的属性。

复制代码
// 示例代码

AppStorage.setOrCreate('appTheme', 'light');

PersistentStorage.persistProp('appTheme');

从应用逻辑和UI内部使用存储

在应用逻辑中,可以通过AppStorage的静态方法来进行状态的设置和获取。而在UI内部,通过@StorageProp和@StorageLink装饰器,可以将组件的属性与AppStorage中的属性进行绑定,实现数据的双向同步。

复制代码
// 示例代码

@StorageProp('counter')

counter: number = 0;

@StorageLink('userToken')

userToken: string = '';

上述代码中,counter和userToken分别与AppStorage中的'counter'和'userToken'属性建立了关联。这样,在UI中修改这些属性时,AppStorage中的数据会同步更新,反之亦然。

不建议借助@StorageLink的双向同步实现事件通知

虽然@StorageLink提供了双向同步的机制,但不建议将其用于事件通知。因为AppStorage是与UI相关的数据存储,修改会触发UI的刷新,而事件通知的成本相对较大。推荐使用emitter方式来实现事件通知,提高代码的可读性和性能。

复制代码
// 不推荐的示例代码

@StorageLink('tapIndex')

tapIndex: number = -1;

// 推荐的示例代码

import emitter from '@ohos.events.emitter';

emitter.on('onTapIndexChange', (data) => {

// 处理事件通知

});

通过emitter方式,我们可以更灵活地实现事件的订阅和发布,避免不必要的UI刷新,提高应用的性能。

示例演练

为了更好地理解AppStorage和LocalStorage的使用,让我们通过一个简单的示例演练来展示它们的实际应用。

复制代码
// 示例演练代码

// AppStorage示例

@StorageProp('appCounter')

appCounter: number = 0;

// LocalStorage示例

let pageStorage: LocalStorage = new LocalStorage();

@Component

struct App {

build() {

Column() {

// 显示AppStorage中的计数器值

Text(`App Counter: ${this.appCounter}`);

// 显示LocalStorage中的页面标题

Text(`Page Title: ${pageStorage.get('pageTitle')}`);

// 按钮,点击时AppStorage计数器加1

Button('Increment App Counter')

.onClick(() => {

this.appCounter += 1;

});

// 按钮,点击时修改LocalStorage中的页面标题

Button('Change Page Title')

.onClick(() => {

pageStorage.set('pageTitle', 'New Page Title');

});

}

}

}

// 在另一个组件中使用@StorageLink

@StorageLink('appCounter')

counterFromLink: number = 0;

@Component

struct AnotherComponent {

build() {

Column() {

// 显示通过@StorageLink关联的AppStorage计数器值

Text(`Counter from Link: ${this.counterFromLink}`);

}

}

}

上述代码中,我们创建了一个App组件,其中使用了@StorageProp和LocalStorage,演示了如何在应用级别(AppStorage)和页面级别(LocalStorage)进行状态管理。另外,通过在另一个组件中使用@StorageLink,展示了如何在不同组件之间实现状态的双向同步。

限制条件和最佳实践

在使用AppStorage和LocalStorage时,我们需要注意一些限制条件和最佳实践:

  1. 调用顺序问题: 在AppStorage中创建属性后,调用PersistentStorage.persistProp()接口时,会使用在AppStorage中已经存在的值,并覆盖PersistentStorage中的同名属性。因此,建议在使用PersistentStorage前访问AppStorage中的属性。
  2. 属性命名注意事项: 如果在AppStorage中已经创建属性后,再调用Environment.envProp()创建同名的属性,会调用失败。因此,建议AppStorage中的属性不要使用Environment预置环境变量名。
  3. 状态装饰器和事件通知: 状态装饰器装饰的变量改变会引起UI的渲染更新。如果改变的变量不是用于UI更新,只是用于消息传递,推荐使用emitter方式来实现事件通知,以减小UI刷新的成本。
  4. 合理使用@StorageProp和@StorageLink: 在应用逻辑中,可以通过AppStorage的静态方法来进行状态的设置和获取。而在UI内部,通过@StorageProp和@StorageLink装饰器,可以将组件的属性与AppStorage中的属性进行绑定,实现数据的双向同步。但要注意不要滥用双向同步机制,以避免不必要的性能开销。
  5. 事件通知的优化: 不建议借助@StorageLink的双向同步机制实现事件通知。由于AppStorage是与UI相关的数据存储,修改会触发UI的刷新,而事件通知的成本相对较大。推荐使用emitter方式来实现事件通知,提高代码的可读性和性能。

结语

通过深入理解ARKTS中的AppStorage和LocalStorage,我们能够更好地利用这两个特性进行应用状态的管理和共享。合理使用这些工具,可以提高代码的可维护性和性能,使得开发更加高效。在实际开发中,根据具体需求和场景选择合适的状态管理方式,将有助于构建更健壮、可扩展的HarmonyOS应用。

ARKTS中的AppStorage和LocalStorage为开发者提供了强大的状态管理工具,使得应用程序能够高效地共享和管理状态数据。通过与PersistentStorage和Environment的协作,可以实现更全面的状态管理和数据持久化。在开发过程中,合理使用@StorageProp和@StorageLink等装饰器,以及emitter方式,能够更好地组织和维护应用的状态逻辑。

点击关注,第一时间了解华为云新鲜技术~

相关推荐
鸿蒙布道师5 小时前
鸿蒙NEXT开发资源工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
葱段7 小时前
【Harmony】ArkUI全局设置窗口背景颜色、页面背景颜色
harmonyos·arkts·arkui
鸿蒙布道师10 小时前
鸿蒙NEXT开发设备相关工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
槐月杰15 小时前
2025ArkTS基础UI(一)——Column、Row、Text组件
ui·arkts·鸿蒙·鸿蒙系统
威哥爱编程1 天前
HarmonyOS NEXT 实现滑动拼图验证码功能
华为·harmonyos·arkts
马剑威(威哥爱编程)1 天前
HarmonyOS NEXT 实现滑动拼图验证码功能
华为·harmonyos·arkts
Huang兄2 天前
鸿蒙-状态管理V1和V2在ForEach循环渲染的表现
harmonyos·arkts·arkui
鸿蒙布道师2 天前
鸿蒙NEXT开发全局异常捕获与崩溃日志收集工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
鸿蒙布道师2 天前
鸿蒙NEXT开发节流、防抖工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
鸿蒙布道师3 天前
鸿蒙NEXT开发文件操作相关工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei