AppStorageV2: 应用全局UI状态存储
developer.huawei.com/consumer/cn…
AppStorageV2是在应用UI启动时会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorageV2将在应用运行过程保留其数据。数据通过唯一的键字符串值访问
转换前
/**
*
* AppStorageV2Cmp.ets
* Created by unravel on 2024/8/2
* @abstract
*/
import { router, AppStorageV2 } from '@kit.ArkUI';
// 数据中心
@ObservedV2
export class Sample {
@Trace p1: number = 0;
p2: number = 10;
}
@ComponentV2
export struct AppStorageV2Cmp {
// 在AppStorageV2中创建一个key为Sample的键值对(如果存在,则返回AppStorageV2中的数据),并且和prop关联
@Local prop: Sample = AppStorageV2.connect(Sample, () => new Sample())!;
build() {
Column() {
Button('Go to page2')
.onClick(() => {
router.pushUrl({
url: 'pages/Page2'
})
})
Button('Page1 connect the key Sample')
.onClick(() => {
// 在AppStorageV2中创建一个key为Sample的键值对(如果存在,则返回AppStorageV2中的数据),并且和prop关联
this.prop = AppStorageV2.connect(Sample, 'Sample', () => new Sample())!;
})
Button('Page1 remove the key Sample')
.onClick(() => {
// 从AppStorageV2中删除后,prop将不会再与key为Sample的值关联
AppStorageV2.remove(Sample);
})
Text(`Page1 add 1 to prop.p1: ${this.prop.p1}`)
.fontSize(30)
.onClick(() => {
this.prop.p1++;
})
Text(`Page1 add 1 to prop.p2: ${this.prop.p2}`)
.fontSize(30)
.onClick(() => {
// 页面不刷新,但是p2的值改变了
this.prop.p2++;
})
// 获取当前AppStorageV2里面的所有key
Text(`all keys in AppStorage: ${AppStorageV2.keys()}`)
.fontSize(30)
}
}
}
转换后
if (!("finalizeConstruction" in ViewPU.prototype)) {
Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
import router from "@ohos:router";
import { AppStorageV2 } from "@ohos:arkui.StateManagement";
// 数据中心
@ObservedV2
export class Sample {
@Trace
p1: number = 0;
p2: number = 10;
}
export class AppStorageV2Cmp extends ViewV2 {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
super(parent, elmtId, extraInfo);
this.prop = AppStorageV2.connect(Sample, () => new Sample())!;
this.finalizeConstruction();
}
// 在AppStorageV2中创建一个key为Sample的键值对(如果存在,则返回AppStorageV2中的数据),并且和prop关联
@Local
prop: Sample;
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel('Go to page2');
Button.onClick(() => {
router.pushUrl({
url: 'pages/Page2'
});
});
}, Button);
Button.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel('Page1 connect the key Sample');
Button.onClick(() => {
// 在AppStorageV2中创建一个key为Sample的键值对(如果存在,则返回AppStorageV2中的数据),并且和prop关联
this.prop = AppStorageV2.connect(Sample, 'Sample', () => new Sample())!;
});
}, Button);
Button.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel('Page1 remove the key Sample');
Button.onClick(() => {
// 从AppStorageV2中删除后,prop将不会再与key为Sample的值关联
AppStorageV2.remove(Sample);
});
}, Button);
Button.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`Page1 add 1 to prop.p1: ${this.prop.p1}`);
Text.fontSize(30);
Text.onClick(() => {
this.prop.p1++;
});
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`Page1 add 1 to prop.p2: ${this.prop.p2}`);
Text.fontSize(30);
Text.onClick(() => {
// 页面不刷新,但是p2的值改变了
this.prop.p2++;
});
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
// 获取当前AppStorageV2里面的所有key
Text.create(`all keys in AppStorage: ${AppStorageV2.keys()}`);
// 获取当前AppStorageV2里面的所有key
Text.fontSize(30);
}, Text);
// 获取当前AppStorageV2里面的所有key
Text.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
AppStorageV2 类
AppStorageV2.appStorageV2Impl_ = AppStorageV2Impl.instance();
class AppStorageV2Impl extends StorageHelper
public connect(type: TypeConstructorWithArgs, keyOrDefaultCreator?: string | StorageDefaultCreator, defaultCreator?: StorageDefaultCreator): T | undefined
从这里我们也看出,存储的实际上是一个对象的引用,然后App内多个页面之所以能够同步是因为他们访问的是同一个对象
AppStorageV2本身没有观察数据的变化,实际驱动UI刷新的动作还需要数据自身来完成,即对应的class必须使用ObservedV2和Trace装饰