LocalStorage是页面级的UI状态存储,通过@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility实例内,在页面间共享状态。
本文仅介绍LocalStorage使用场景和相关的装饰器:@LocalStorageProp和@LocalStorageLink。
说明
- 本模块从API version 9开始支持。
概述
LocalStorage是ArkTS为构建页面级别状态变量提供存储的内存内"数据库"。
- 应用程序可以创建多个LocalStorage实例,LocalStorage实例可以在页面内共享,也可以通过GetShared接口,实现跨页面、UIAbility实例内共享。
- 组件树的根节点,即被@Entry装饰的@Component,可以被分配一个LocalStorage实例,此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限;
- 被@Component装饰的组件最多可以访问一个LocalStorage实例和AppStorage,未被@Entry装饰的组件不可被独立分配LocalStorage实例,只能接受父组件通过@Entry传递来的LocalStorage实例。一个LocalStorage实例在组件树上可以被分配给多个组件。
- LocalStorage中的所有属性都是可变的。
应用程序决定LocalStorage对象的生命周期。当应用释放最后一个指向LocalStorage的引用时,比如销毁最后一个自定义组件,LocalStorage将被JS Engine垃圾回收。
LocalStorage根据与@Component装饰的组件的同步类型不同,提供了两个装饰器:
- @LocalStorageProp:@LocalStorageProp装饰的变量和与LocalStorage中给定属性建立单向同步关系。
- @LocalStorageLink:@LocalStorageLink装饰的变量和在@Component中创建与LocalStorage中给定属性建立双向同步关系。
1.先看下@LocalStorageLink
js
import { TodoListViewModel } from '../viewModel/TodoListViewModel'
import {TodoListItem} from '../common/components/TodoListItem'
import TodoListConstants from '../common/constants/TodoListConstants'
import HarmonyStoreUtils from '../uitils/HarmonyStoreUtils'
let storage:LocalStorage = new LocalStorage({'showSwitchTips2':false});
@Entry(storage)
@Component
export struct TodoList{
// @LocalStorageLink变量装饰器与LocalStorage中的'PropA'属性建立双向绑定
@LocalStorageLink('PropA') storLink2: number = 1;
@LocalStorageLink('PropB') storLinkB: boolean = false;
@State dataSource:any[] =[]
build(){
Column({space:16}){
Text(`待办${this.storLink2}PropB=${this.storLinkB}`)
.fontSize(16)
.fontStyle(FontStyle.Normal)
.fontWeight(FontWeight.Bold)
.margin({bottom:20})
.textAlign(TextAlign.Start)
.width(TodoListConstants.TITLE_WIDTH)
.onClick(()=>{
// HarmonyStoreUtils.testLocalStorage()
// this.printStorageKeys();
// // this.showSwitchTipsLink = true;
// let linkShowSwitchTips2=storage.link('showSwitchTips2')
// linkShowSwitchTips2.set(true)
// console.log(`==========showSwitchTipsLink=${this.showSwitchTipsLink}`)
// HarmonyStoreUtils.testLocalStorage()
// this.printStorageKeys();
this.storLink2 += 1
this.storLinkB = !this.storLinkB
})
ForEach(this.dataSource,(item,index)=>{
TodoListItem({index:item.index+1,name:item.name})
},item =>JSON.stringify(item))
Child()
}.justifyContent(FlexAlign.Start)
.width(TodoListConstants.FULL_SCREEN_WIDTH)
.height(TodoListConstants.FULL_SCREEN_WIDTH)
}
aboutToAppear(){
this.dataSource = new TodoListViewModel().loadData()
}
printStorageKeys(){
let keys:IterableIterator<string>= storage.keys();
console.log(">>>>>>Component LocalStorage>>>>>>");
for (let key of keys) {
let showSwitchTips = storage.get(key)
console.log(`Component>>>>>>${key}:${showSwitchTips}`);
}
console.log(`------鸿蒙迭代器的遍历-----`);
// for (const [name,value] of keys) { //for IterableIterator<[string, string]>
// console.log(`鸿蒙迭代器的遍历>>>>>>name=${name},value=${value}`);
//
// }
for (const [name] of keys) {
console.log(`鸿蒙迭代器的遍历>>>>>>key=${name}`);
}
console.log(`------鸿蒙迭代器的遍历-end----`);
}
}
@Component
struct Child {
// @LocalStorageLink变量装饰器与LocalStorage中的'PropA'属性建立双向绑定
@LocalStorageLink('PropA') storLink2: number = 1;
@LocalStorageLink('PropB') storLink2B: boolean = false;
build() {
Button(`Child from LocalStorage ${this.storLink2}${this.storLink2B}`)
// 更改将同步至LocalStorage中的'PropA'以及Parent.storLink1
.onClick(() => {
this.storLink2 += 1
this.storLink2B =!this.storLink2B
})
}
}
效果演示:
2.页面间LocalStorage数据共享实例
- EntryAbility中设置要共享的数据
js
storage:LocalStorage;
para:Record<string, number> = { 'showNumber': 3 };
windowStage.loadContent('pages/MainPage',this.storage, (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
- 各page通过LocalStorage.GetShared()获取要共享的LocalStorage
- 通过第2步获得的storage对象获取存储在LocalStorage中的字段。
这种方法在处理UI界面恢复时特别有用
运行效果: