鸿蒙 7 AppStorage 全局状态:跨页面全局状态、登录态持久化实战
前面学的 @State / @Link / @ObjectLink 都是组件 / 父子之间的状态。一旦需要跨页面共享数据(比如登录 token、用户信息、全局主题),单纯靠路由传参非常麻烦。ArkTS 提供 AppStorage,专门用来存放应用全局状态,整个 App 所有页面都可以读取、监听。
一句话理解:AppStorage 是全局的状态仓库,数据存在应用内存;搭配
PersistentStorage可以把数据持久化到本地,App 重启后数据还在(适合记住登录状态)。
一、AppStorage 基础概念
- AppStorage:全局内存存储,应用运行期间有效,App 关闭就清空。
- 可以在任意页面读写、监听变化;
- 推荐用
@StorageProp/@StorageLink装饰器绑定,自动响应数据变化;@StorageProp:单向绑定,读取全局数据,本地修改不回写全局(本地副本)@StorageLink:双向绑定,修改变量,全局仓库同步更新
误区:不要把所有数据都塞进 AppStorage。只放全局共享数据:token、用户信息、主题、全局配置;页面局部状态继续用 @State,全局仓库放太多数据会增加性能开销。
1. 基础用法:@StorageLink 双向绑定全局变量
import AppStorage from '@ohos.app.ability.AppStorage';
// 初始化全局变量(建议放在入口页面/ability中一次性初始化)
AppStorage.setOrCreate('userName', '游客');
@Entry
@Component
struct PageA {
// 双向绑定全局key:userName
@StorageLink('userName') globalName: string;
build() {
Column() {
Text(`全局用户名:${this.globalName}`).fontSize(22)
Button("修改全局名字")
.onClick(() => {
this.globalName = "小明";
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
新建 PageB.ets,在另一个页面读取同一份全局数据:
@Entry
@Component
struct PageB {
@StorageLink('userName') globalName: string;
build() {
Column() {
Text(`PageB读取全局名字:${this.globalName}`).fontSize(22)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
关键点:
AppStorage.setOrCreate(key, 默认值):如果 key 不存在就创建,存在就不覆盖;@StorageLink('key'):双向绑定,当前组件修改,所有绑定这个 key 的页面全部自动刷新 UI;- key 是字符串,全局唯一。

2. @StorageProp 单向全局读取(副本)
@Entry
@Component
struct StoragePropDemo {
// 单向:从全局读取,本地修改只是副本,不会改动AppStorage
@StorageProp('userName') localName: string;
build() {
Column() {
Text(`单向读取全局:${this.localName}`)
Button("修改本地副本(不会改全局)")
.onClick(() => {
this.localName = "临时名字";
})
}
}
}
- @StorageProp:拿到的是副本;本地修改不会同步到全局;
- 但如果源头 AppStorage 的值被别的页面修改,当前页面会自动同步最新值。
3. 复杂对象存入 AppStorage(用户信息实体)
⚠️重点:对象存入 AppStorage,class 必须加
@ObservedObject,否则修改对象内部属性 UI 不刷新。
import AppStorage from '@ohos.app.ability.AppStorage';
@ObservedObject
class User {
id: number;
name: string;
token: string;
constructor(id: number, name: string, token: string) {
this.id = id;
this.name = name;
this.token = token;
}
}
// 初始化全局用户对象
AppStorage.setOrCreate('loginUser', new User(0, "游客", ""));
@Entry
@Component
struct GlobalUserDemo {
@StorageLink('loginUser') user: User;
build() {
Column() {
Text(`用户:${this.user.name},token:${this.user.token}`).fontSize(18)
Button("登录,更新全局用户信息")
.onClick(() => {
this.user.id = 1001;
this.user.name = "张三";
this.user.token = "abc123456";
})
Button("退出登录")
.onClick(() => {
this.user = new User(0, "游客", "");
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
4. PersistentStorage 持久化:App 重启依然保留登录态
AppStorage 只是内存存储,App 杀掉之后数据丢失。 PersistentStorage 可以把指定 key 持久化到本地数据库,App 重启、手机重启,数据还在,适合保存记住登录、主题设置。
import PersistentStorage from '@ohos.app.ability.PersistentStorage';
import AppStorage from '@ohos.app.ability.AppStorage';
// 在EntryAbility.ts的onCreate里面初始化持久化
// 把AppStorage里面的loginToken开启持久化
PersistentStorage.persistProp('loginToken', '');
// 页面中使用
@Entry
@Component
struct PersistDemo {
@StorageLink('loginToken') token: string;
build() {
Column() {
Text(`本地保存的token:${this.token}`)
Button("保存token")
.onClick(() => {
this.token = "test_token_666";
})
Button("清空token")
.onClick(() => {
this.token = "";
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
关键点:
- persistProp (key, 默认值),推荐放在 EntryAbility.ts onCreate,App 启动时加载;
- 持久化只支持基础类型:string、number、boolean;复杂 class 对象不能直接持久化,对象持久化需要手动转 JSON 字符串存储。

5. 原生 API:直接读写 AppStorage(不绑定装饰器)
有时候不在 UI 组件里(比如 http 请求工具类),不能使用 @StorageLink,直接调用 API 读写:
import AppStorage from '@ohos.app.ability.AppStorage';
// 设置
AppStorage.set('userName', "李四");
// 获取
const name = AppStorage.get<string>('userName');
// 删除key
AppStorage.delete('userName');
六、AppStorage 高频踩坑汇总
坑 1:复杂对象不加 @ObservedObject,修改内部属性页面不刷新
class 实体必须加 @ObservedObject,否则对象内部字段变更不会触发 UI 更新。
坑 2:PersistentStorage 直接持久化 class 对象
❌错误:persistProp 存 User 对象。持久化仅支持基础类型,对象需要 JSON.stringify 转字符串存入,读取再 JSON.parse 还原。
坑 3:全局 key 命名冲突
多个地方定义同名 key,数据互相覆盖。建议统一维护全局 key 常量。
坑 4:滥用 AppStorage,大量页面状态放全局
局部页面状态不要进全局仓库,会造成状态难以追踪、调试困难。
坑 5:忘记初始化 setOrCreate,@StorageLink 绑定 undefined
页面直接 @StorageLink 绑定 key,没有提前初始化,容易出现 undefined 报错。推荐在 EntryAbility 初始化全局默认值。
七、全局状态选型速查表
| API / 装饰器 | 作用 | 数据位置 | 生命周期 |
|---|---|---|---|
| AppStorage | 全局状态仓库 | 内存 | App 运行期间,关闭 App 清空 |
| @StorageLink('key') | 双向绑定全局 key | 内存 | 修改同步全局,UI 自动刷新 |
| @StorageProp('key') | 单向读取全局,本地副本 | 内存 | 源头变更同步,本地修改不回写 |
| PersistentStorage | 持久化存储 | 本地文件数据库 | App 重启、手机重启数据保留(仅基础类型) |
结尾总结
- AppStorage 是应用全局内存状态,跨页面共享登录信息、全局配置;
- @StorageLink 双向绑定,@StorageProp 单向副本;
- 复杂 class 实体存入 AppStorage,类必须加 @ObservedObject;
- PersistentStorage 持久化仅支持基础类型,用来保存 token、主题开关;对象持久化要手动 JSON 序列化;
- 尽量精简全局仓库,局部状态继续使用 @State。
实操指南
- 在 EntryAbility 初始化全局登录用户(@ObservedObject User 类);
- 登录页点击登录,更新 AppStorage 用户信息;
- 首页读取全局用户信息展示;
- token 用 PersistentStorage 持久化保存,重启 App 仍然保留登录凭证。
更多推荐



所有评论(0)