掌握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时,我们需要注意一些限制条件和最佳实践:
- 调用顺序问题: 在AppStorage中创建属性后,调用PersistentStorage.persistProp()接口时,会使用在AppStorage中已经存在的值,并覆盖PersistentStorage中的同名属性。因此,建议在使用PersistentStorage前访问AppStorage中的属性。
- 属性命名注意事项: 如果在AppStorage中已经创建属性后,再调用Environment.envProp()创建同名的属性,会调用失败。因此,建议AppStorage中的属性不要使用Environment预置环境变量名。
- 状态装饰器和事件通知: 状态装饰器装饰的变量改变会引起UI的渲染更新。如果改变的变量不是用于UI更新,只是用于消息传递,推荐使用emitter方式来实现事件通知,以减小UI刷新的成本。
- 合理使用@StorageProp和@StorageLink: 在应用逻辑中,可以通过AppStorage的静态方法来进行状态的设置和获取。而在UI内部,通过@StorageProp和@StorageLink装饰器,可以将组件的属性与AppStorage中的属性进行绑定,实现数据的双向同步。但要注意不要滥用双向同步机制,以避免不必要的性能开销。
- 事件通知的优化: 不建议借助@StorageLink的双向同步机制实现事件通知。由于AppStorage是与UI相关的数据存储,修改会触发UI的刷新,而事件通知的成本相对较大。推荐使用emitter方式来实现事件通知,提高代码的可读性和性能。
结语
通过深入理解ARKTS中的AppStorage和LocalStorage,我们能够更好地利用这两个特性进行应用状态的管理和共享。合理使用这些工具,可以提高代码的可维护性和性能,使得开发更加高效。在实际开发中,根据具体需求和场景选择合适的状态管理方式,将有助于构建更健壮、可扩展的HarmonyOS应用。
ARKTS中的AppStorage和LocalStorage为开发者提供了强大的状态管理工具,使得应用程序能够高效地共享和管理状态数据。通过与PersistentStorage和Environment的协作,可以实现更全面的状态管理和数据持久化。在开发过程中,合理使用@StorageProp和@StorageLink等装饰器,以及emitter方式,能够更好地组织和维护应用的状态逻辑。
掌握HarmonyOS框架的ArkTs如何管理和共享状态数据的更多相关文章
- ASP.NET MVC搭建项目后台UI框架—6、客户管理(添加、修改、查询、分页)
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列
http://www.cnblogs.com/hanyinglong/archive/2013/03/22/2976478.html ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(21)-用户角色权限基本的实现说明
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(21)-用户角色权限基本的实现说明 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(19)-用户信息的修改和浏览
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(19)-用户信息的修改和浏览 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(18)-过滤器的使用和批量删除数据(伪删除和直接删除)
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(18)-过滤器的使用和批量删除数据(伪删除和直接删除) ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证)
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证) ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(16)-类库架构扩展以及DLL文件生成修改和用户的简单添加
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(16)-类库架构扩展以及DLL文件生成修改和用户的简单添加 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 (2 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(15)-用户登录详细错误和权限数据库模型设计
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(15)-用户登录详细错误和权限数据库模型设计 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) ...
随机推荐
- axios快速上手(简单使用)
axios对ajax请求进行了封装,并且使用promise的链式调用使得网络请求的代码逻辑更为清晰,同时支持async和await的编写方式使代码看起来像同步,更加方便于理解和阅读.axios这个库的 ...
- 形象谈JVM-第三章-即时编译器优化技术
即时编译器优化技术一览: 相信许多同学看完这个表格,脑子里面嗡嗡的,这些名字也是晦涩难懂,要实现这些优化的技术确实有比较大的难度,但是咱们只是学习,去理解这些技术,其实并不难,下面咱们直接开讲. 首先 ...
- WPF-封装自定义雷达图控件
源码地址:https://gitee.com/LiuShuiRuoBing/code_blog 雷达图用于表示不同内容的占比关系,在项目中有广泛的应用,但是目前未曾有封装良好的雷达图控件,鉴于最近项目 ...
- 修改DataTable中的值
DataTable dt ;for (int i = 0; i < dt.Rows.Count; i++) { DataRow row = dt.Rows[i]; row.BeginEdit() ...
- Codeforces 1257D - Yet Another Monster Killing Problem
题意: 有\(n\)个怪物,每个怪物有攻击力\(a_i\)点:有\(m\)个英雄,每个英雄有攻击力\(p_i\)点,耐力\(s_{i}\)点. 怪物需要被依次杀死(按输入顺序). 每一天可以挑选一个英 ...
- Poor God Water(ACM-ICPC 2018 焦作赛区网络预赛 矩阵快速幂)
题目描述 God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells ...
- 超全技术学习资料PDF分享
技术学习资料分享,目前共20G,持续更新... Java学习资料: 大数据Hadoop: 这里不一一截图了,资源持续更新中. 关注下面公众号进行下载.
- 入门篇-其之二-Java基础知识
目录 对第一个Java程序的思考 外层结构--类 内层结构--main方法 输出语句 注释 单行注释 多行注释 文档注释 文档注释常用标签 使用javadoc命令生成网页风格的文档 阿里巴巴Java开 ...
- Linux安装达梦数据库DM8
1.简介描述 DM8是达梦公司在总结DM系列产品研发与应用经验的基础上,坚持开放创新.简洁实用的理念,推出的新一代自研数据库.DM8吸收借鉴当前先进新技术思想与主流数据库产品的优点,融合了分布式.弹性 ...
- 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(5) -- 树列表TreeView的使用
在我们展示一些参考信息的时候,有所会用树形列表来展示结构信息,如对于有父子关系的多层级部门机构,以及一些常用如字典大类节点,也都可以利用树形列表的方式进行展示,本篇随笔介绍基于WPF的方式,使用Tre ...