鸿蒙 页面级UI状态存储LocalStorage解析
摘要: LocalStorage是ArkTS提供的页面级状态存储方案,用于页面内或UIAbility实例内多页面间的UI状态共享。通过@LocalStorageProp(单向同步)和@LocalStorageLink(双向同步)装饰器实现数据绑定,前者仅接收LocalStorage更新,后者支持双向同步。需注意:属性类型不可更改、初始值必填、生命周期与页面关联,持久化数据需用PersistentS
本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、LocalStorage 概述
LocalStorage 是 ArkTS 为构建页面级别状态变量提供存储的内存内“数据库”。它主要用于页面内或 UIAbility 实例内多个页面间的 UI 状态共享。
- 作用:提供页面级 UI 状态存储 。
- 特性:存储在内存中,应用程序可以创建多个 LocalStorage 实例。这些实例可以在页面内共享,也可以通过 getSharedLocalStorage 接口实现跨页面、UIAbility 实例内共享 。
- 生命周期:由应用程序决定。当应用释放最后一个指向 LocalStorage 的引用时(例如销毁最后一个使用它的自定义组件),LocalStorage 会被 JS Engine 垃圾回收 。
- 与装饰器的关系:LocalStorage 通过与
@Component
装饰的组件不同的同步类型,提供了两个装饰器:@LocalStorageProp
:与 LocalStorage 中给定属性建立单向同步关系。@LocalStorageLink
:与 LocalStorage 中给定属性建立双向同步关系。
二、LocalStorage 的使用
1. 创建与初始化
创建一个 LocalStorage 实例,并使用一个对象(键值对形式)进行初始化:
// 准备共享数据
const data: Record<string, string> = {
'uname': '张三',
'age': '18'
};
// 创建LocalStorage实例
const storage = new LocalStorage(data);
2. 与组件关联
组件树的根节点(即被 @Entry
装饰的 @Component
)可以被分配一个 LocalStorage 实例。此组件的所有子组件实例将自动获得对该 LocalStorage 实例的访问权限。
@Entry(storage) // 将storage实例与根组件关联
@Component
struct TestLocalStorage03 {
// 组件内使用LocalStorage
}
未被 @Entry
装饰的组件不会被独立分配 LocalStorage 实例,只能接受父组件通过 @Entry
传递来的 LocalStorage 实例。
3. 装饰器使用规则
@LocalStorageProp (单向同步)
项目 | 说明 |
---|---|
装饰器参数 | key :常量字符串,必填(字符串需要有引号)。 |
允许装饰的变量类型 | Object、class、string、number、boolean、enum 类型,以及这些类型的数组。API version 12 及以上支持 Map、Set、Date、undefined 和 null 类型。 |
同步类型 | 单向同步:从 LocalStorage 的对应属性到组件的状态变量。组件本地的修改是允许的,但 LocalStorage 中给定的属性一旦发生变化,将覆盖本地的修改 。 |
被装饰变量的初始值 | 必须指定。如果 LocalStorage 实例中不存在属性,则作为初始化默认值,并存入 LocalStorage 中。 |
- 特点:
- 允许本地修改,但本地修改不会同步回 LocalStorage 中。
- 如果 LocalStorage 中 key 对应的属性值改变(如通过
.set
接口修改),会同步给@LocalStorageProp
并覆盖本地值 。 - 不支持装饰Function类型。
- 示例:
@Entry(storage)
@Component
struct CompA {
@LocalStorageProp('uname') storageProp1: string = 'defaultName'; // 单向同步
build() {
Column() {
Text(`Parent from LocalStorage: ${this.storageProp1}`)
Button('Change locally')
.onClick(() => {
this.storageProp1 = 'LocalChange'; // 仅本地变化,不会同步回storage
})
}
}
}
@LocalStorageLink (双向同步)
项目 | 说明 |
---|---|
装饰器参数 | key :常量字符串,必填(字符串需要有引号)。 |
允许装饰的变量类型 | Object、class、string、number、boolean、enum 类型,以及这些类型的数组。API version 12 及以上支持 Map、Set、Date、undefined 和 null 类型。 |
同步类型 | 双向同步:任何一方的修改都会同步到另一方。 |
- 特点:
- 与
@LocalStorageProp
类似,但建立的是双向同步关系。 - 本地修改会同步回 LocalStorage,LocalStorage 中对应属性的修改也会同步到所有绑定该属性的
@LocalStorageLink
变量。 - 不支持装饰Function类型。
- 与
- 示例:
@Entry(storage)
@Component
struct CompA {
@LocalStorageLink('uname') storageLink1: string = 'defaultName'; // 双向同步
build() {
Column() {
Text(`Parent from LocalStorage: ${this.storageLink1}`)
Button('Change and sync to LocalStorage')
.onClick(() => {
this.storageLink1 = 'NewName'; // 本地变化会同步回storage
})
}
}
}
@Component
struct Child {
@LocalStorageLink('uname') storageLink2: string = 'defaultName'; // 双向同步
build() {
Column() {
Text(`Child from LocalStorage: ${this.storageLink2}`) // 会随Parent的修改或storage的修改而改变
}
}
}
4. 在 UIAbility 中共享给多个页面
在 UIAbility 的 onWindowStageCreate
生命周期中,可以将 LocalStorage 实例传递给多个页面,实现 UIAbility 内多个页面间的状态共享:
export default class EntryAbility extends UIAbility {
storage: LocalStorage = new LocalStorage({
'abilitycount': 1
});
onWindowStageCreate(windowStage: window.WindowStage): void {
// 将storage传递给页面'pages/Index'
windowStage.loadContent('pages/Index', this.storage, (err, data) => {
if (err.code) {
// 错误处理
return;
}
});
}
}
在页面中,可以通过 LocalStorage.
getSharedLocalStorage()
方法获取在 UIAbility 中共享的 LocalStorage 实例。
三、注意事项
- 命名属性的类型不可更改:LocalStorage 创建后,命名属性的类型就确定了。后续调用
set
方法时必须使用相同类型的值 。 getShared
接口的限制:getSharedLocalStorage 接口仅能获取当前 Stage 通过windowStage.loadContent
传入的 LocalStorage 实例,否则返回undefined
。- 初始值是必须的:使用
@LocalStorageProp
或@LocalStorageLink
装饰变量时,必须指定初始值。如果 LocalStorage 实例中不存在对应的属性,将使用这个初始值,并会将其存入 LocalStorage 中 。
- 页面级存储:LocalStorage 是页面级存储,其生命周期与页面相关联。对于需要持久化的数据(如用户登录 token、应用配置等),应考虑使用
PersistentStorage
或其他持久化方案 。 - 多组件共享:一个 LocalStorage 实例在组件树上可以被分配给多个组件 。
四、使用场景
- 页面内组件间状态共享:例如,一个页面中多个组件需要响应同一个状态的变化 。
- UIAbility 内多个页面间状态共享:例如,在一个 UIAbility 内跳转的不同页面需要共享某些 UI 状态 。
- 与服务卡片的数据更新:通过 LocalStorage 可以更新服务卡片中显示的数据 。
五、@LocalStorageProp 与 @LocalStorageLink 对比
特性 | @LocalStorageProp | @LocalStorageLink |
---|---|---|
同步方式 | 单向同步 (LocalStorage -> 组件) | 双向同步 |
本地修改是否同步回 LocalStorage | 否 | 是 |
是否需要初始值 | 是 | 是 |
适用场景 | 仅需接收 LocalStorage 变化,本地修改不需同步回去 | 需要与 LocalStorage 保持双向数据一致 |
六、总结
LocalStorage 是鸿蒙应用开发中用于管理页面级UI状态的重要工具,它提供了一种在内存中存储和共享数据的机制,特别适用于组件间或同一UIAbility内页面间的状态同步。
选择 @LocalStorageProp
还是 @LocalStorageLink
,取决于数据流需求:是简单的接收更新,还是需要双向的交互。同时,务必注意其生命周期是页面级的,对于需要持久化的数据,应选择 PersistentStorage
等其他方案。
更多推荐
所有评论(0)