中国最权威的网站排名,网上商店系统设计与开发,网站建设技术部职责,长春建站模板制作LocalStorage是页面级的UI状态存储#xff0c;通过Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility实例内#xff0c;在页面间共享状态。
本文仅介绍LocalStorage使用场景和相关的装饰器#xff1a;LocalStorageProp和LocalS…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装饰的组件的同步类型不同提供了两个装饰器
LocalStoragePropLocalStorageProp装饰的变量和与LocalStorage中给定属性建立单向同步关系。LocalStorageLinkLocalStorageLink装饰的变量和在Component中创建与LocalStorage中给定属性建立双向同步关系。
限制条件
LocalStorage创建后命名属性的类型不可更改。后续调用Set时必须使用相同类型的值。LocalStorage是页面级存储GetShared接口仅能获取当前Stage通过windowStage.loadContent传入的LocalStorage实例否则返回undefined。例子可见将LocalStorage实例从UIAbility共享到一个或多个视图。
LocalStorageProp
在上文中已经提到如果要建立LocalStorage和自定义组件的联系需要使用LocalStorageProp和LocalStorageLink装饰器。使用LocalStorageProp(key)/LocalStorageLink(key)装饰组件内的变量key标识了LocalStorage的属性。
当自定义组件初始化的时候LocalStorageProp(key)/LocalStorageLink(key)装饰的变量会通过给定的key绑定LocalStorage对应的属性完成初始化。本地初始化是必要的因为无法保证LocalStorage一定存在给定的key这取决于应用逻辑是否在组件初始化之前在LocalStorage实例中存入对应的属性。 ⚠️注意 从API version 9开始该装饰器支持在ArkTS卡片中使用。 LocalStorageProp(key)是和LocalStorage中key对应的属性建立单向数据同步我们允许本地改变的发生但是对于LocalStorageProp本地的修改永远不会同步回LocalStorage中相反如果LocalStorage给定key的属性发生改变改变会被同步给LocalStorageProp并覆盖掉本地的修改。
装饰器使用规则说明
LocalStorageProp变量装饰器说明装饰器参数key常量字符串必填字符串需要有引号。允许装饰的变量类型Object、class、string、number、boolean、enum类型以及这些类型的数组。嵌套类型的场景请参考观察变化和行为表现。类型必须被指定且必须和LocalStorage中对应属性相同。不支持any不允许使用undefined和null。同步类型单向同步从LocalStorage的对应属性到组件的状态变量。组件本地的修改是允许的但是LocalStorage中给定的属性一旦发生变化将覆盖本地的修改。被装饰变量的初始值必须指定如果LocalStorage实例中不存在属性则作为初始化默认值并存入LocalStorage中。
变量的传递/访问规则说明
传递/访问说明从父节点初始化和更新禁止LocalStorageProp不支持从父节点初始化只能从LocalStorage中key对应的属性初始化如果没有对应key的话将使用本地默认值初始化。初始化子节点支持可用于初始化State、Link、Prop、Provide。是否支持组件外访问否
LocalStorageProp初始化规则图示
观察变化和行为表现
观察变化 当装饰的数据类型为boolean、string、number类型时可以观察到数值的变化。 当装饰的数据类型为class或者Object时可以观察到赋值和属性赋值的变化即 Object.keys(observedObject)返回的所有属性。 当装饰的对象是array时可以观察到数组添加、删除、更新数组单元的变化。
框架行为
当LocalStorageProp(key)装饰的数值改变被观察到时修改不会被同步回LocalStorage对应属性键值key的属性中。当前LocalStorageProp(key)单向绑定的数据会被修改即仅限于当前组件的私有成员变量改变其他的绑定该key的数据不会同步改变。当LocalStorageProp(key)装饰的数据本身是状态变量它的改变虽然不会同步回LocalStorage中但是会引起所属的自定义组件的重新渲染。当LocalStorage中key对应的属性发生改变时会同步给所有LocalStorageProp(key)装饰的数据LocalStorageProp(key)本地的修改将被覆盖。
LocalStorageLink
如果我们需要将自定义组件的状态变量的更新同步回LocalStorage就需要用LocalStorageLink。
LocalStorageLink(key)是和LocalStorage中key对应的属性建立双向数据同步
本地修改发生该修改会被写回LocalStorage中LocalStorage中的修改发生后该修改会被同步到所有绑定LocalStorage对应key的属性上包括单向LocalStorageProp和通过prop创建的单向绑定变量、双向LocalStorageLink和通过link创建的双向绑定变量变量。
装饰器使用规则说明
LocalStorageLink变量装饰器说明装饰器参数key常量字符串必填字符串需要有引号。允许装饰的变量类型Object、class、string、number、boolean、enum类型以及这些类型的数组。嵌套类型的场景请参考观察变化和行为表现。类型必须被指定且必须和LocalStorage中对应属性相同。不支持any不允许使用undefined和null。同步类型双向同步从LocalStorage的对应属性到自定义组件从自定义组件到LocalStorage对应属性。被装饰变量的初始值必须指定如果LocalStorage实例中不存在属性则作为初始化默认值并存入LocalStorage中。
变量的传递/访问规则说明
传递/访问说明从父节点初始化和更新禁止LocalStorageLink不支持从父节点初始化只能从LocalStorage中key对应的属性初始化如果没有对应key的话将使用本地默认值初始化。初始化子节点支持可用于初始化State、Link、Prop、Provide。是否支持组件外访问否
LocalStorageLink初始化规则图示
观察变化和行为表现
观察变化
当装饰的数据类型为boolean、string、number类型时可以观察到数值的变化。当装饰的数据类型为class或者Object时可以观察到赋值和属性赋值的变化即Object.keys(observedObject)返回的所有属性。当装饰的对象是array时可以观察到数组添加、删除、更新数组单元的变化。
框架行为
当LocalStorageLink(key)装饰的数值改变被观察到时修改将被同步回LocalStorage对应属性键值key的属性中。LocalStorage中属性键值key对应的数据一旦改变属性键值key绑定的所有的数据包括双向LocalStorageLink和单向LocalStorageProp都将同步修改。当LocalStorageLink(key)装饰的数据本身是状态变量它的改变不仅仅会同步回LocalStorage中还会引起所属的自定义组件的重新渲染。
使用场景
应用逻辑使用LocalStorage
let storage new LocalStorage({ PropA: 47 }); // 创建新实例并使用给定对象初始化
let propA storage.get(PropA) // propA 47
let link1 storage.link(PropA); // link1.get() 47
let link2 storage.link(PropA); // link2.get() 47
let prop storage.prop(PropA); // prop.get() 47
link1.set(48); // two-way sync: link1.get() link2.get() prop.get() 48
prop.set(1); // one-way sync: prop.get()1; but link1.get() link2.get() 48
link1.set(49); // two-way sync: link1.get() link2.get() prop.get() 49从UI内部使用LocalStorage
除了应用程序逻辑使用LocalStorage还可以借助LocalStorage相关的两个装饰器LocalStorageProp和LocalStorageLink在UI组件内部获取到LocalStorage实例中存储的状态变量。
本示例以LocalStorageLink为例展示了
使用构造函数创建LocalStorage实例storage使用Entry装饰器将storage添加到CompA顶层组件中LocalStorageLink绑定LocalStorage对给定的属性建立双向数据同步。
// 创建新实例并使用给定对象初始化
let storage new LocalStorage({ PropA: 47 });Component
struct Child {// LocalStorageLink变量装饰器与LocalStorage中的PropA属性建立双向绑定LocalStorageLink(PropA) storLink2: number 1;build() {Button(Child from LocalStorage ${this.storLink2})// 更改将同步至LocalStorage中的PropA以及Parent.storLink1.onClick(() this.storLink2 1)}
}
// 使LocalStorage可从Component组件访问
Entry(storage)
Component
struct CompA {// LocalStorageLink变量装饰器与LocalStorage中的PropA属性建立双向绑定LocalStorageLink(PropA) storLink1: number 1;build() {Column({ space: 15 }) {Button(Parent from LocalStorage ${this.storLink1}) // initial value from LocalStorage will be 47, because PropA initialized already.onClick(() this.storLink1 1)// Component子组件自动获得对CompA LocalStorage实例的访问权限。Child()}}
}LocalStorageProp和LocalStorage单向同步的简单场景
在下面的示例中CompA 组件和Child组件分别在本地创建了与storage的’PropA’对应属性的单向同步的数据我们可以看到
CompA中对this.storProp1的修改只会在CompA中生效并没有同步回storageChild组件中Text绑定的storProp2 依旧显示47。
// 创建新实例并使用给定对象初始化
let storage new LocalStorage({ PropA: 47 });
// 使LocalStorage可从Component组件访问
Entry(storage)
Component
struct CompA {// LocalStorageProp变量装饰器与LocalStorage中的PropA属性建立单向绑定LocalStorageProp(PropA) storProp1: number 1;build() {Column({ space: 15 }) {// 点击后从47开始加1只改变当前组件显示的storProp1不会同步到LocalStorage中Button(Parent from LocalStorage ${this.storProp1}).onClick(() this.storProp1 1)Child()}}
}Component
struct Child {// LocalStorageProp变量装饰器与LocalStorage中的PropA属性建立单向绑定LocalStorageProp(PropA) storProp2: number 2;build() {Column({ space: 15 }) {// 当CompA改变时当前storProp2不会改变显示47Text(Parent from LocalStorage ${this.storProp2})}}
}LocalStorageLink和LocalStorage双向同步的简单场景
下面的示例展示了LocalStorageLink装饰的数据和LocalStorage双向同步的场景
// 构造LocalStorage实例
let storage new LocalStorage({ PropA: 47 });
// 调用linkapi9以上接口构造PropA的双向同步数据linkToPropA 是全局变量
let linkToPropA storage.link(PropA);Entry(storage)
Component
struct CompA {// LocalStorageLink(PropA)在CompA自定义组件中创建PropA的双向同步数据初始值为47因为在构造LocalStorage已经给“PropA”设置47LocalStorageLink(PropA) storLink: number 1;build() {Column() {Text(incr LocalStorageLink variable)// 点击“incr LocalStorageLink variable”this.storLink加1改变同步回storage全局变量linkToPropA也会同步改变 .onClick(() this.storLink 1)// 并不建议在组件内使用全局变量linkToPropA.get()因为可能会有生命周期不同引起的错误。Text(LocalStorageLink: ${this.storLink} - linkToPropA: ${linkToPropA.get()})}}
}兄弟节点之间同步状态变量
下面的示例展示了通过LocalStorageLink双向同步兄弟节点之间的状态。
先看Parent自定义组件中发生的变化
点击“playCount ${this.playCount} dec by 1”this.playCount减1修改同步回LocalStorage中Child组件中的playCountLink绑定的组件会同步刷新点击“countStorage ${this.playCount} incr by 1”调用LocalStorage的set接口更新LocalStorage中“countStorage”对应的属性Child组件中的playCountLink绑定的组件会同步刷新Text组件“playCount in LocalStorage for debug ${storage.get(‘countStorage’)}”没有同步刷新因为storage.get(‘countStorage’)返回的是常规变量常规变量的更新并不会引起Text组件的重新渲染。
Child自定义组件中的变化playCountLink的刷新会同步回LocalStorage并且引起兄弟组件和父组件相应的刷新。
let storage new LocalStorage({ countStorage: 1 });Component
struct Child {// 子组件实例的名字label: string no name;// 和LocalStorage中“countStorage”的双向绑定数据LocalStorageLink(countStorage) playCountLink: number 0;build() {Row() {Text(this.label).width(50).height(60).fontSize(12)Text(playCountLink ${this.playCountLink}: inc by 1).onClick(() {this.playCountLink 1;}).width(200).height(60).fontSize(12)}.width(300).height(60)}
}Entry(storage)
Component
struct Parent {LocalStorageLink(countStorage) playCount: number 0;build() {Column() {Row() {Text(Parent).width(50).height(60).fontSize(12)Text(playCount ${this.playCount} dec by 1).onClick(() {this.playCount - 1;}).width(250).height(60).fontSize(12)}.width(300).height(60)Row() {Text(LocalStorage).width(50).height(60).fontSize(12)Text(countStorage ${this.playCount} incr by 1).onClick(() {storage.setnumber(countStorage, 1 storage.getnumber(countStorage));}).width(250).height(60).fontSize(12)}.width(300).height(60)Child({ label: ChildA })Child({ label: ChildB })Text(playCount in LocalStorage for debug ${storage.getnumber(countStorage)}).width(300).height(60).fontSize(12)}}
}将LocalStorage实例从UIAbility共享到一个或多个视图
上面的实例中LocalStorage的实例仅仅在一个Entry装饰的组件和其所属的子组件一个页面中共享如果希望其在多个视图中共享可以在所属UIAbility中创建LocalStorage实例并调用windowStage.loadContent。
// EntryAbility.ts
import UIAbility from ohos.app.ability.UIAbility;
import window from ohos.window;export default class EntryAbility extends UIAbility {
para:Recordstring, number { PropA: 47 };
storage: LocalStorage new LocalStorage(this.para);onWindowStageCreate(windowStage: window.WindowStage) {
windowStage.loadContent(pages/Index, this.storage);
}
}⚠️ 注意 在UI页面通过getShared接口获取在通过loadContent共享的LocalStorage实例。 LocalStorage.getShared只在模拟器或者实机上才有效不能在Preview预览器中使用。 在下面的用例中Index页面中的propA通过getShared()方法获取到共享的LocalStorage实例。点击Button跳转到Page页面点击Change propA改变propA的值back回Index页面后页面中propA的值也同步修改。
// index.ets
import router from ohos.router;// 通过getShared接口获取stage共享的LocalStorage实例
let storage LocalStorage.getShared()
Entry(storage)
Component
struct Index {// can access LocalStorage instance using // LocalStorageLink/Prop decorated variablesLocalStorageLink(PropA) propA: number 1;build() {Row() {Column() {Text(${this.propA}).fontSize(50).fontWeight(FontWeight.Bold)Button(To Page).onClick(() {router.pushUrl({url:pages/Page})})}.width(100%)}.height(100%)}
}// Page.ets
import router from ohos.router;let storage LocalStorage.getShared()
Entry(storage)
Component
struct Page {LocalStorageLink(PropA) propA: number 2;build() {Row() {Column() {Text(${this.propA}).fontSize(50).fontWeight(FontWeight.Bold)Button(Change propA).onClick(() {this.propA 100;})Button(Back Index).onClick(() {router.back()})}.width(100%)}}
}⚠️ 注意 对于开发者更建议使用这个方式来构建LocalStorage的实例并且在创建LocalStorage实例的时候就写入默认值因为默认值可以作为运行异常的备份也可以用作页面的单元测试。 总结
LocalStorage是页面级的UI状态存储通过Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility实例内在页面间共享状态。