鸿蒙应用开发:AppStorage 全局状态存储用法教程

这是一个使用鸿蒙技术开发的本地原生记账应用,非常适合大家用来练手。相关源码已上传至 Github,点击此处查看项目。欢迎大家交流、指正,也欢迎提交 PR。

一、引言

在鸿蒙应用开发中,跨页面、跨组件的数据共享是一个常见需求。

想象一下,用户登录后,他的用户名需要在个人中心、订单页面、消息列表等多个地方展示。如果不使用全局状态管理,你需要把用户名一层层通过路由参数、函数参数等方式传递下去(即"Prop Drilling"),代码会变得非常冗长且难以维护。AppStorage 就是为了解决这类问题而生的,它让你的组件可以随时"连接"到一个全局的数据仓库,直接读写,无需繁琐的中间传递。

AppStorage------一个应用级别的全局 UI 状态存储中心,由 UI 框架在应用启动时自动创建。它的核心作用是让不同页面、不同组件之间能够方便地共享和响应式更新数据。

二、基本用法

2.1 初始化与设置

使用 AppStorage.setOrCreate(key, value) 在应用启动时(如 UIAbility 的 onCreate 中)初始化一个全局状态。如果该 key 已存在,则不会覆盖;如果不存在,则创建。

typescript 复制代码
onCreate(want, launchParam) {
  // 设置一个全局的登录状态,默认为 false
  AppStorage.setOrCreate('isLoggedIn', false);
  // 设置用户信息
  AppStorage.setOrCreate('userName', '未登录用户');
}

2.2 绑定到组件

AppStorage 提供了两种装饰器来将组件变量与全局状态绑定:

  • @StorageProp(key) :将组件变量与 AppStorage 中的属性进行单向绑定 。组件内部修改该变量不会同步回 AppStorage,适合只读场景。
  • @StorageLink(key) :实现双向绑定 。组件内部修改该变量会自动同步回 AppStorage,并触发所有绑定该属性的组件更新。
typescript 复制代码
@Entry
@Component
struct MyComponent {
  // 单向绑定:组件内修改不会影响全局
  @StorageProp('appTheme') theme: string = 'light';
  // 双向绑定:组件内修改会同步到全局
  @StorageLink('isLoggedIn') isLoggedIn: boolean = false;
}

2.3 外部修改

在组件外部(如非 UI 层的服务、工具类中),可以通过 AppStorage.set(key, value) 直接修改状态,所有绑定了该状态的组件会自动刷新。

typescript 复制代码
// 在任意位置修改全局状态
AppStorage.set('isLoggedIn', true);
AppStorage.set('userName', '张三');

三、示例:管理用户登录状态

以下示例展示了如何使用 AppStorage 和 @StorageLink 实现一个全局的登录状态管理,实现跨页面的状态同步。

3.1 在应用入口初始化全局状态

typescript 复制代码
// 1. 在应用入口(如 UIAbility)中初始化全局状态

// 应用启动时,设置一个全局的登录状态,默认为 false
AppStorage.setOrCreate('isLoggedIn', false);

3.2 登录页面组件

typescript 复制代码
// 2. 在页面组件中使用 @StorageLink 进行双向绑定
import { router } from '@kit.ArkUI';

@Entry
@Component
struct LoginPage {
  // 双向绑定 AppStorage 中的 'isLoggedIn' 属性
  @StorageLink('isLoggedIn') isLoggedIn: boolean = false;

  build() {
    Column({space: 20}) {
      Text(`当前登录状态: ${this.isLoggedIn ? '已登录' : '未登录'}`)
        .fontSize(20)
      if (this.isLoggedIn) {
        // 已登录状态
        Button('退出登录')
          .width("80%")
          .onClick(() => {
            // 修改 @StorageLink 变量,会自动同步到 AppStorage
            this.isLoggedIn = false;
          })
      } else {
        Button('登录')
          .width("80%")
          .onClick(() => {
            // 修改 @StorageLink 变量,会自动同步到 AppStorage
            this.isLoggedIn = true;
            router.push({
              url: "pages/ProfilePage"
            })
          })

        Button("个人中心")
          .width("80%")
          .onClick(() => {
            router.push({
              url: "pages/ProfilePage"
            })
          })
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

3.3 个人中心页面组件

typescript 复制代码
// 3. 在另一个页面中,也可以直接读取同一个全局状态
@Entry
@Component
struct ProfilePage {
  // 同样绑定 'isLoggedIn' 属性
  @StorageLink('isLoggedIn') isLoggedIn: boolean = false;

  build() {
    Column() {
      Text(`当前登录状态: ${this.isLoggedIn ? '已登录' : '未登录'}`)
        .fontSize(20)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

在这个例子中,当用户在 LoginPage 点击"登录"按钮后,isLoggedIn 变为 true。这个变化会立即同步到 AppStorage,并自动通知所有绑定了 @StorageLink('isLoggedIn') 的组件(如 ProfilePage)进行重新渲染,从而实现了跨页面的状态同步。

运行效果:

四、进阶用法与注意事项

4.1 删除状态

使用 AppStorage.delete(key) 可以删除某个全局状态。

typescript 复制代码
AppStorage.delete('userName');

只要通过 @StorageProp 或 @StorageLink 引用了某个键,该键就无法被 delete 方法删除。这是为了防止因数据源被意外删除而导致 UI 显示异常。此时可以通过 AppStorage.set 更新其值。

4.2 清空与获取所有键

使用 AppStorage.clear() 可以清空 AppStorage 中的所有状态,此操作不可逆,请谨慎使用。

typescript 复制代码
// 清空所有全局状态
AppStorage.clear();

使用 AppStorage.keys() 可以获取当前 AppStorage 中所有已存储的键名,返回一个字符串数组,便于调试或遍历处理。

typescript 复制代码
// 获取所有键名
const allKeys: string[] = AppStorage.keys();
console.info('当前 AppStorage 中的键:', JSON.stringify(allKeys));

4.3 注意事项

  • 应用生命周期 :AppStorage 在应用启动时创建,应用退出时销毁,适合存储应用级别的全局状态。
  • 数据类型 :支持基本类型(number、string、boolean)以及 Object、Array 等复杂类型,但复杂类型的修改需要替换整个对象才能触发响应式更新。
  • 性能考虑 :不要将大量数据或频繁变化的数据全部放入 AppStorage,建议只存储跨页面共享的关键状态。
  • 与 LocalStorage 的区别 :AppStorage 是应用级全局单例,而 LocalStorage 是页面级共享存储,作用范围不同。

五、总结

AppStorage 是鸿蒙 ArkTS 中非常实用的全局状态管理工具,通过 @StorageProp 和 @StorageLink 装饰器,可以轻松实现跨页面、跨组件的数据共享与响应式更新。合理使用 AppStorage 能够显著简化应用状态管理逻辑,提升开发效率。

相关推荐
一次旅行1 小时前
DeepSeek‑V4.1‑Flash‑1017完整解读:模型升级+Search/Fetch搜索API开放,Agent开发者要注意哪些坑
前端·网络·人工智能
原则猫9 小时前
UDP 到底怎么实现可靠的
前端
Java后端的Ai之路9 小时前
14、ReactJS - 路由(Router)
前端·react.js·状态模式
裕晟资质规划11 小时前
三类涉密资质延续时限差异分析:军工60日与集成印制3个月的边界
java·服务器·前端·网络·安全
ShineWinsu11 小时前
对于JavaScript:JavaScript基础语法的解析
开发语言·前端·javascript·面试·web·基础语法·循环
月夏11 小时前
Vue3 转 React:18 项对照表 + 5 个必踩的坑(附 7 天上手路线)
前端
广州华水科技11 小时前
单北斗GNSS位移监测系统的应用与维护解析
前端
马剑威(威哥爱编程)11 小时前
【共创稿事节】HarmonyOS 7 Agent 开发实战 11:并发多会话隔离
华为·harmonyos
梦曦i12 小时前
uni-storage 0.1.0 发布:TTL过期管理+多实例隔离
前端·storage·uni-app x
猫头_12 小时前
AI 流式传输工程指南:模型吐出半截 JSON,前端如何边收边渲染?
前端·javascript·llm