1e41f4b71Sopenharmony_ci# LocalStorage:页面级UI状态存储 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciLocalStorage是页面级的UI状态存储,通过\@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage支持UIAbility实例内多个页面间状态共享。 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci本文仅介绍LocalStorage使用场景和相关的装饰器:\@LocalStorageProp和\@LocalStorageLink。 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci> **说明:** 11e41f4b71Sopenharmony_ci> 12e41f4b71Sopenharmony_ci> LocalStorage从API version 9开始支持。 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci## 概述 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ciLocalStorage是ArkTS为构建页面级别状态变量提供存储的内存内的“数据库”。 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci- 应用程序可以创建多个LocalStorage实例,LocalStorage实例可以在页面内共享,也可以通过GetShared接口,实现跨页面、UIAbility实例内共享。 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci- 组件树的根节点,即被\@Entry装饰的\@Component,可以被分配一个LocalStorage实例,此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限。 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci- 被\@Component装饰的组件最多可以访问一个LocalStorage实例和[AppStorage](arkts-appstorage.md),未被\@Entry装饰的组件不可被独立分配LocalStorage实例,只能接受父组件通过\@Entry传递来的LocalStorage实例。一个LocalStorage实例在组件树上可以被分配给多个组件。 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci- LocalStorage中的所有属性都是可变的。 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci应用程序决定LocalStorage对象的生命周期。当应用释放最后一个指向LocalStorage的引用时,比如销毁最后一个自定义组件,LocalStorage将被JS Engine垃圾回收。 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ciLocalStorage根据与\@Component装饰的组件的同步类型不同,提供了两个装饰器: 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci- [@LocalStorageProp](#localstorageprop):\@LocalStorageProp装饰的变量与LocalStorage中给定属性建立单向同步关系。 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ci- [@LocalStorageLink](#localstoragelink):\@LocalStorageLink装饰的变量与LocalStorage中给定属性建立双向同步关系。 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ci## 限制条件 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci- LocalStorage创建后,命名属性的类型不可更改。后续调用Set时必须使用相同类型的值。 39e41f4b71Sopenharmony_ci- LocalStorage是页面级存储,[getShared](../reference/apis-arkui/arkui-ts/ts-state-management.md#getshared10)接口仅能获取当前Stage通过[windowStage.loadContent](../reference/apis-arkui/js-apis-window.md#loadcontent9)传入的LocalStorage实例,否则返回undefined。例子可见[将LocalStorage实例从UIAbility共享到一个或多个视图](#将localstorage实例从uiability共享到一个或多个视图)。 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci 42e41f4b71Sopenharmony_ci## \@LocalStorageProp 43e41f4b71Sopenharmony_ci 44e41f4b71Sopenharmony_ci在上文中已经提到,如果要建立LocalStorage和自定义组件的联系,需要使用\@LocalStorageProp和\@LocalStorageLink装饰器。使用\@LocalStorageProp(key)/\@LocalStorageLink(key)装饰组件内的变量,key标识了LocalStorage的属性。 45e41f4b71Sopenharmony_ci 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci当自定义组件初始化的时候,\@LocalStorageProp(key)/\@LocalStorageLink(key)装饰的变量会通过给定的key,绑定LocalStorage对应的属性,完成初始化。本地初始化是必要的,因为无法保证LocalStorage一定存在给定的key(这取决于应用逻辑是否在组件初始化之前在LocalStorage实例中存入对应的属性)。 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ci> **说明:** 51e41f4b71Sopenharmony_ci> 52e41f4b71Sopenharmony_ci> 从API version 9开始,该装饰器支持在ArkTS卡片中使用。 53e41f4b71Sopenharmony_ci> 54e41f4b71Sopenharmony_ci> 从API version 11开始,该装饰器支持在原子化服务中使用。 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci\@LocalStorageProp(key)是和LocalStorage中key对应的属性建立单向数据同步,ArkUI框架支持修改@LocalStorageProp(key)在本地的值,但是对本地值的修改不会同步回LocalStorage中。相反,如果LocalStorage中key对应的属性值发生改变,例如通过set接口对LocalStorage中的值进行修改,改变会同步给\@LocalStorageProp(key),并覆盖掉本地的值。 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci### 装饰器使用规则说明 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci| \@LocalStorageProp变量装饰器 | 说明 | 62e41f4b71Sopenharmony_ci| ----------------------- | ---------------------------------------- | 63e41f4b71Sopenharmony_ci| 装饰器参数 | key:常量字符串,必填(字符串需要有引号)。 | 64e41f4b71Sopenharmony_ci| 允许装饰的变量类型 | Object、class、string、number、boolean、enum类型,以及这些类型的数组。<br/>API12及以上支持Map、Set、Date类型。嵌套类型的场景请参考[观察变化和行为表现](#观察变化和行为表现)。<br/>类型必须被指定,建议和LocalStorage中对应属性类型相同,否则会发生类型隐式转换,从而导致应用行为异常。<br/>不支持any,API12及以上支持undefined和null类型。<br/>API12及以上支持上述支持类型的联合类型,比如string \| number, string \| undefined 或者 ClassA \| null,示例见[LocalStorage支持联合类型](#localstorage支持联合类型)。 <br/>**注意**<br/>当使用undefined和null的时候,建议显式指定类型,遵循TypeScript类型校验,比如:`@LocalStorageProp("AA") a: number \| null = null`是推荐的,不推荐`@LocalStorageProp("AA") a: number = null`。 | 65e41f4b71Sopenharmony_ci| 同步类型 | 单向同步:从LocalStorage的对应属性到组件的状态变量。组件本地的修改是允许的,但是LocalStorage中给定的属性一旦发生变化,将覆盖本地的修改。 | 66e41f4b71Sopenharmony_ci| 被装饰变量的初始值 | 必须指定,如果LocalStorage实例中不存在属性,则用该初始值初始化该属性,并存入LocalStorage中。 | 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ci### 变量的传递/访问规则说明 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci| 传递/访问 | 说明 | 72e41f4b71Sopenharmony_ci| ---------- | ---------------------------------------- | 73e41f4b71Sopenharmony_ci| 从父节点初始化和更新 | 禁止,\@LocalStorageProp不支持从父节点初始化,只能从LocalStorage中key对应的属性初始化,如果没有对应key的话,将使用本地默认值初始化。 | 74e41f4b71Sopenharmony_ci| 初始化子节点 | 支持,可用于初始化\@State、\@Link、\@Prop、\@Provide。 | 75e41f4b71Sopenharmony_ci| 是否支持组件外访问 | 否。 | 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ci **图1** \@LocalStorageProp初始化规则图示 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci### 观察变化和行为表现 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci**观察变化** 85e41f4b71Sopenharmony_ci 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci- 当装饰的数据类型为boolean、string、number类型时,可以观察到数值的变化。 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_ci- 当装饰的数据类型为class或者Object时,可以观察到对象整体赋值和对象属性变化(详见[从ui内部使用localstorage](#从ui内部使用localstorage))。 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ci- 当装饰的对象是array时,可以观察到数组添加、删除、更新数组单元的变化。 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci- 当装饰的对象是Date时,可以观察到Date整体的赋值,同时可通过调用Date的接口`setFullYear`, `setMonth`, `setDate`, `setHours`, `setMinutes`, `setSeconds`, `setMilliseconds`, `setTime`, `setUTCFullYear`, `setUTCMonth`, `setUTCDate`, `setUTCHours`, `setUTCMinutes`, `setUTCSeconds`, `setUTCMilliseconds` 更新Date的属性。详见[装饰Date类型变量](#装饰date类型变量)。 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci- 当装饰的变量是Map时,可以观察到Map整体的赋值,同时可通过调用Map的接口`set`, `clear`, `delete` 更新Map的值。详见[装饰Map类型变量](#装饰map类型变量)。 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci- 当装饰的变量是Set时,可以观察到Set整体的赋值,同时可通过调用Set的接口`add`, `clear`, `delete` 更新Set的值。详见[装饰Set类型变量](#装饰set类型变量)。 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_ci**框架行为** 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci 103e41f4b71Sopenharmony_ci- 被\@LocalStorageProp装饰的变量的值的变化不会同步回LocalStorage里。 104e41f4b71Sopenharmony_ci 105e41f4b71Sopenharmony_ci- \@LocalStorageProp装饰的变量变化会使当前自定义组件中关联的组件刷新。 106e41f4b71Sopenharmony_ci 107e41f4b71Sopenharmony_ci- LocalStorage(key)中值的变化会引发所有被\@LocalStorageProp对应key装饰的变量的变化,会覆盖\@LocalStorageProp本地的改变。 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ci 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci## \@LocalStorageLink 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci> **说明:** 115e41f4b71Sopenharmony_ci> 116e41f4b71Sopenharmony_ci> 从API version 11开始,该装饰器支持在原子化服务中使用。 117e41f4b71Sopenharmony_ci 118e41f4b71Sopenharmony_ci如果我们需要将自定义组件的状态变量的更新同步回LocalStorage,就需要用到\@LocalStorageLink。 119e41f4b71Sopenharmony_ci 120e41f4b71Sopenharmony_ci\@LocalStorageLink(key)是和LocalStorage中key对应的属性建立双向数据同步: 121e41f4b71Sopenharmony_ci 122e41f4b71Sopenharmony_ci1. 本地修改发生,该修改会被写回LocalStorage中; 123e41f4b71Sopenharmony_ci 124e41f4b71Sopenharmony_ci2. LocalStorage中的修改发生后,该修改会被同步到所有绑定LocalStorage对应key的属性上,包括单向(\@LocalStorageProp和通过prop创建的单向绑定变量)、双向(\@LocalStorageLink和通过link创建的双向绑定变量)变量。 125e41f4b71Sopenharmony_ci 126e41f4b71Sopenharmony_ci### 装饰器使用规则说明 127e41f4b71Sopenharmony_ci 128e41f4b71Sopenharmony_ci| \@LocalStorageLink变量装饰器 | 说明 | 129e41f4b71Sopenharmony_ci| ----------------------- | ---------------------------------------- | 130e41f4b71Sopenharmony_ci| 装饰器参数 | key:常量字符串,必填(字符串需要有引号)。 | 131e41f4b71Sopenharmony_ci| 允许装饰的变量类型 | Object、class、string、number、boolean、enum类型,以及这些类型的数组。<br/>API12及以上支持Map、Set、Date类型。嵌套类型的场景请参考[观察变化和行为表现](#观察变化和行为表现)。<br/>类型必须被指定,建议和LocalStorage中对应属性类型相同,否则会发生类型隐式转换,从而导致应用行为异常。<br/>不支持any,API12及以上支持undefined和null类型。<br/>API12及以上支持上述支持类型的联合类型,比如string \| number, string \| undefined 或者 ClassA \| null,示例见[LocalStorage支持联合类型](#localstorage支持联合类型)。 <br/>**注意**<br/>当使用undefined和null的时候,建议显式指定类型,遵循TypeScript类型校验,比如:`@LocalStorageLink("AA") a: number \| null = null`是推荐的,不推荐`@LocalStorageLink("AA") a: number = null`。 | 132e41f4b71Sopenharmony_ci| 同步类型 | 双向同步:从LocalStorage的对应属性到自定义组件,从自定义组件到LocalStorage对应属性。 | 133e41f4b71Sopenharmony_ci| 被装饰变量的初始值 | 必须指定,如果LocalStorage实例中不存在属性,则用该初始值初始化该属性,并存入LocalStorage中。 | 134e41f4b71Sopenharmony_ci 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci### 变量的传递/访问规则说明 137e41f4b71Sopenharmony_ci 138e41f4b71Sopenharmony_ci| 传递/访问 | 说明 | 139e41f4b71Sopenharmony_ci| ---------- | ---------------------------------------- | 140e41f4b71Sopenharmony_ci| 从父节点初始化和更新 | 禁止,\@LocalStorageLink不支持从父节点初始化,只能从LocalStorage中key对应的属性初始化,如果没有对应key的话,将使用本地默认值初始化。 | 141e41f4b71Sopenharmony_ci| 初始化子节点 | 支持,可用于初始化\@State、\@Link、\@Prop、\@Provide。 | 142e41f4b71Sopenharmony_ci| 是否支持组件外访问 | 否。 | 143e41f4b71Sopenharmony_ci 144e41f4b71Sopenharmony_ci 145e41f4b71Sopenharmony_ci **图2** \@LocalStorageLink初始化规则图示 146e41f4b71Sopenharmony_ci 147e41f4b71Sopenharmony_ci 148e41f4b71Sopenharmony_ci 149e41f4b71Sopenharmony_ci 150e41f4b71Sopenharmony_ci 151e41f4b71Sopenharmony_ci### 观察变化和行为表现 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci**观察变化** 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_ci 156e41f4b71Sopenharmony_ci- 当装饰的数据类型为boolean、string、number类型时,可以观察到数值的变化。 157e41f4b71Sopenharmony_ci 158e41f4b71Sopenharmony_ci- 当装饰的数据类型为class或者Object时,可以观察到对象整体赋值和对象属性变化(详见[从ui内部使用localstorage](#从ui内部使用localstorage))。 159e41f4b71Sopenharmony_ci 160e41f4b71Sopenharmony_ci- 当装饰的对象是array时,可以观察到数组添加、删除、更新数组单元的变化。 161e41f4b71Sopenharmony_ci 162e41f4b71Sopenharmony_ci- 当装饰的对象是Date时,可以观察到Date整体的赋值,同时可通过调用Date的接口`setFullYear`, `setMonth`, `setDate`, `setHours`, `setMinutes`, `setSeconds`, `setMilliseconds`, `setTime`, `setUTCFullYear`, `setUTCMonth`, `setUTCDate`, `setUTCHours`, `setUTCMinutes`, `setUTCSeconds`, `setUTCMilliseconds` 更新Date的属性。详见[装饰Date类型变量](#装饰date类型变量)。 163e41f4b71Sopenharmony_ci 164e41f4b71Sopenharmony_ci- 当装饰的变量是Map时,可以观察到Map整体的赋值,同时可通过调用Map的接口`set`, `clear`, `delete` 更新Map的值。详见[装饰Map类型变量](#装饰map类型变量)。 165e41f4b71Sopenharmony_ci 166e41f4b71Sopenharmony_ci- 当装饰的变量是Set时,可以观察到Set整体的赋值,同时可通过调用Set的接口`add`, `clear`, `delete` 更新Set的值。详见[装饰Set类型变量](#装饰set类型变量)。 167e41f4b71Sopenharmony_ci 168e41f4b71Sopenharmony_ci 169e41f4b71Sopenharmony_ci**框架行为** 170e41f4b71Sopenharmony_ci 171e41f4b71Sopenharmony_ci 172e41f4b71Sopenharmony_ci1. 当\@LocalStorageLink(key)装饰的数值改变被观察到时,修改将被同步回LocalStorage对应属性键值key的属性中。 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ci2. LocalStorage中属性键值key对应的数据一旦改变,属性键值key绑定的所有的数据(包括双向\@LocalStorageLink和单向\@LocalStorageProp)都将同步修改。 175e41f4b71Sopenharmony_ci 176e41f4b71Sopenharmony_ci3. 当\@LocalStorageLink(key)装饰的数据本身是状态变量,它的改变不仅仅会同步回LocalStorage中,还会引起所属的自定义组件的重新渲染。 177e41f4b71Sopenharmony_ci 178e41f4b71Sopenharmony_ci 179e41f4b71Sopenharmony_ci 180e41f4b71Sopenharmony_ci 181e41f4b71Sopenharmony_ci## 使用场景 182e41f4b71Sopenharmony_ci 183e41f4b71Sopenharmony_ci 184e41f4b71Sopenharmony_ci### 应用逻辑使用LocalStorage 185e41f4b71Sopenharmony_ci 186e41f4b71Sopenharmony_ci 187e41f4b71Sopenharmony_ci```ts 188e41f4b71Sopenharmony_cilet para: Record<string,number> = { 'PropA': 47 }; 189e41f4b71Sopenharmony_cilet storage: LocalStorage = new LocalStorage(para); // 创建新实例并使用给定对象初始化 190e41f4b71Sopenharmony_cilet propA: number | undefined = storage.get('PropA') // propA == 47 191e41f4b71Sopenharmony_cilet link1: SubscribedAbstractProperty<number> = storage.link('PropA'); // link1.get() == 47 192e41f4b71Sopenharmony_cilet link2: SubscribedAbstractProperty<number> = storage.link('PropA'); // link2.get() == 47 193e41f4b71Sopenharmony_cilet prop: SubscribedAbstractProperty<number> = storage.prop('PropA'); // prop.get() == 47 194e41f4b71Sopenharmony_cilink1.set(48); // two-way sync: link1.get() == link2.get() == prop.get() == 48 195e41f4b71Sopenharmony_ciprop.set(1); // one-way sync: prop.get() == 1; but link1.get() == link2.get() == 48 196e41f4b71Sopenharmony_cilink1.set(49); // two-way sync: link1.get() == link2.get() == prop.get() == 49 197e41f4b71Sopenharmony_ci``` 198e41f4b71Sopenharmony_ci 199e41f4b71Sopenharmony_ci 200e41f4b71Sopenharmony_ci### 从UI内部使用LocalStorage 201e41f4b71Sopenharmony_ci 202e41f4b71Sopenharmony_ci除了应用程序逻辑使用LocalStorage,还可以借助LocalStorage相关的两个装饰器\@LocalStorageProp和\@LocalStorageLink,在UI组件内部获取到LocalStorage实例中存储的状态变量。 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci本示例以\@LocalStorageLink为例,展示了: 205e41f4b71Sopenharmony_ci 206e41f4b71Sopenharmony_ci- 使用构造函数创建LocalStorage实例storage; 207e41f4b71Sopenharmony_ci 208e41f4b71Sopenharmony_ci- 使用\@Entry装饰器将storage添加到CompA顶层组件中; 209e41f4b71Sopenharmony_ci 210e41f4b71Sopenharmony_ci- \@LocalStorageLink绑定LocalStorage对给定的属性,建立双向数据同步。 211e41f4b71Sopenharmony_ci 212e41f4b71Sopenharmony_ci ```ts 213e41f4b71Sopenharmony_ciclass PropB { 214e41f4b71Sopenharmony_ci code: number; 215e41f4b71Sopenharmony_ci 216e41f4b71Sopenharmony_ci constructor(code: number) { 217e41f4b71Sopenharmony_ci this.code = code; 218e41f4b71Sopenharmony_ci } 219e41f4b71Sopenharmony_ci} 220e41f4b71Sopenharmony_ci// 创建新实例并使用给定对象初始化 221e41f4b71Sopenharmony_cilet para: Record<string, number> = { 'PropA': 47 }; 222e41f4b71Sopenharmony_cilet storage: LocalStorage = new LocalStorage(para); 223e41f4b71Sopenharmony_cistorage.setOrCreate('PropB', new PropB(50)); 224e41f4b71Sopenharmony_ci 225e41f4b71Sopenharmony_ci@Component 226e41f4b71Sopenharmony_cistruct Child { 227e41f4b71Sopenharmony_ci // @LocalStorageLink变量装饰器与LocalStorage中的'PropA'属性建立双向绑定 228e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') childLinkNumber: number = 1; 229e41f4b71Sopenharmony_ci // @LocalStorageLink变量装饰器与LocalStorage中的'PropB'属性建立双向绑定 230e41f4b71Sopenharmony_ci @LocalStorageLink('PropB') childLinkObject: PropB = new PropB(0); 231e41f4b71Sopenharmony_ci 232e41f4b71Sopenharmony_ci build() { 233e41f4b71Sopenharmony_ci Column() { 234e41f4b71Sopenharmony_ci Button(`Child from LocalStorage ${this.childLinkNumber}`) // 更改将同步至LocalStorage中的'PropA'以及Parent.parentLinkNumber 235e41f4b71Sopenharmony_ci .onClick(() => { 236e41f4b71Sopenharmony_ci this.childLinkNumber += 1; 237e41f4b71Sopenharmony_ci }) 238e41f4b71Sopenharmony_ci Button(`Child from LocalStorage ${this.childLinkObject.code}`) // 更改将同步至LocalStorage中的'PropB'以及Parent.parentLinkObject.code 239e41f4b71Sopenharmony_ci .onClick(() => { 240e41f4b71Sopenharmony_ci this.childLinkObject.code += 1; 241e41f4b71Sopenharmony_ci }) 242e41f4b71Sopenharmony_ci } 243e41f4b71Sopenharmony_ci } 244e41f4b71Sopenharmony_ci} 245e41f4b71Sopenharmony_ci// 使LocalStorage可从@Component组件访问 246e41f4b71Sopenharmony_ci@Entry(storage) 247e41f4b71Sopenharmony_ci@Component 248e41f4b71Sopenharmony_cistruct CompA { 249e41f4b71Sopenharmony_ci // @LocalStorageLink变量装饰器与LocalStorage中的'PropA'属性建立双向绑定 250e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') parentLinkNumber: number = 1; 251e41f4b71Sopenharmony_ci // @LocalStorageLink变量装饰器与LocalStorage中的'PropB'属性建立双向绑定 252e41f4b71Sopenharmony_ci @LocalStorageLink('PropB') parentLinkObject: PropB = new PropB(0); 253e41f4b71Sopenharmony_ci 254e41f4b71Sopenharmony_ci build() { 255e41f4b71Sopenharmony_ci Column({ space: 15 }) { 256e41f4b71Sopenharmony_ci Button(`Parent from LocalStorage ${this.parentLinkNumber}`) // initial value from LocalStorage will be 47, because 'PropA' initialized already 257e41f4b71Sopenharmony_ci .onClick(() => { 258e41f4b71Sopenharmony_ci this.parentLinkNumber += 1; 259e41f4b71Sopenharmony_ci }) 260e41f4b71Sopenharmony_ci 261e41f4b71Sopenharmony_ci Button(`Parent from LocalStorage ${this.parentLinkObject.code}`) // initial value from LocalStorage will be 50, because 'PropB' initialized already 262e41f4b71Sopenharmony_ci .onClick(() => { 263e41f4b71Sopenharmony_ci this.parentLinkObject.code += 1; 264e41f4b71Sopenharmony_ci }) 265e41f4b71Sopenharmony_ci // @Component子组件自动获得对CompA LocalStorage实例的访问权限。 266e41f4b71Sopenharmony_ci Child() 267e41f4b71Sopenharmony_ci } 268e41f4b71Sopenharmony_ci } 269e41f4b71Sopenharmony_ci} 270e41f4b71Sopenharmony_ci``` 271e41f4b71Sopenharmony_ci 272e41f4b71Sopenharmony_ci 273e41f4b71Sopenharmony_ci### \@LocalStorageProp和LocalStorage单向同步的简单场景 274e41f4b71Sopenharmony_ci 275e41f4b71Sopenharmony_ci在下面的示例中,CompA 组件和Child组件分别在本地创建了与storage的'PropA'对应属性的单向同步的数据,我们可以看到: 276e41f4b71Sopenharmony_ci 277e41f4b71Sopenharmony_ci- CompA中对this.storageProp1的修改,只会在CompA中生效,并没有同步回storage; 278e41f4b71Sopenharmony_ci 279e41f4b71Sopenharmony_ci- Child组件中,Text绑定的storageProp2 依旧显示47。 280e41f4b71Sopenharmony_ci 281e41f4b71Sopenharmony_ci```ts 282e41f4b71Sopenharmony_ci// 创建新实例并使用给定对象初始化 283e41f4b71Sopenharmony_cilet para: Record<string, number> = { 'PropA': 47 }; 284e41f4b71Sopenharmony_cilet storage: LocalStorage = new LocalStorage(para); 285e41f4b71Sopenharmony_ci// 使LocalStorage可从@Component组件访问 286e41f4b71Sopenharmony_ci@Entry(storage) 287e41f4b71Sopenharmony_ci@Component 288e41f4b71Sopenharmony_cistruct CompA { 289e41f4b71Sopenharmony_ci // @LocalStorageProp变量装饰器与LocalStorage中的'PropA'属性建立单向绑定 290e41f4b71Sopenharmony_ci @LocalStorageProp('PropA') storageProp1: number = 1; 291e41f4b71Sopenharmony_ci 292e41f4b71Sopenharmony_ci build() { 293e41f4b71Sopenharmony_ci Column({ space: 15 }) { 294e41f4b71Sopenharmony_ci // 点击后从47开始加1,只改变当前组件显示的storageProp1,不会同步到LocalStorage中 295e41f4b71Sopenharmony_ci Button(`Parent from LocalStorage ${this.storageProp1}`) 296e41f4b71Sopenharmony_ci .onClick(() => { 297e41f4b71Sopenharmony_ci this.storageProp1 += 1 298e41f4b71Sopenharmony_ci }) 299e41f4b71Sopenharmony_ci Child() 300e41f4b71Sopenharmony_ci } 301e41f4b71Sopenharmony_ci } 302e41f4b71Sopenharmony_ci} 303e41f4b71Sopenharmony_ci 304e41f4b71Sopenharmony_ci@Component 305e41f4b71Sopenharmony_cistruct Child { 306e41f4b71Sopenharmony_ci // @LocalStorageProp变量装饰器与LocalStorage中的'PropA'属性建立单向绑定 307e41f4b71Sopenharmony_ci @LocalStorageProp('PropA') storageProp2: number = 2; 308e41f4b71Sopenharmony_ci 309e41f4b71Sopenharmony_ci build() { 310e41f4b71Sopenharmony_ci Column({ space: 15 }) { 311e41f4b71Sopenharmony_ci // 当CompA改变时,当前storageProp2不会改变,显示47 312e41f4b71Sopenharmony_ci Text(`Parent from LocalStorage ${this.storageProp2}`) 313e41f4b71Sopenharmony_ci } 314e41f4b71Sopenharmony_ci } 315e41f4b71Sopenharmony_ci} 316e41f4b71Sopenharmony_ci``` 317e41f4b71Sopenharmony_ci 318e41f4b71Sopenharmony_ci 319e41f4b71Sopenharmony_ci### \@LocalStorageLink和LocalStorage双向同步的简单场景 320e41f4b71Sopenharmony_ci 321e41f4b71Sopenharmony_ci下面的示例展示了\@LocalStorageLink装饰的数据和LocalStorage双向同步的场景: 322e41f4b71Sopenharmony_ci 323e41f4b71Sopenharmony_ci 324e41f4b71Sopenharmony_ci```ts 325e41f4b71Sopenharmony_ci// 构造LocalStorage实例 326e41f4b71Sopenharmony_cilet para: Record<string, number> = { 'PropA': 47 }; 327e41f4b71Sopenharmony_cilet storage: LocalStorage = new LocalStorage(para); 328e41f4b71Sopenharmony_ci// 调用link(api9以上)接口构造'PropA'的双向同步数据,linkToPropA 是全局变量 329e41f4b71Sopenharmony_cilet linkToPropA: SubscribedAbstractProperty<object> = storage.link('PropA'); 330e41f4b71Sopenharmony_ci 331e41f4b71Sopenharmony_ci@Entry(storage) 332e41f4b71Sopenharmony_ci@Component 333e41f4b71Sopenharmony_cistruct CompA { 334e41f4b71Sopenharmony_ci 335e41f4b71Sopenharmony_ci // @LocalStorageLink('PropA')在CompA自定义组件中创建'PropA'的双向同步数据,初始值为47,因为在构造LocalStorage已经给“PropA”设置47 336e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') storageLink: number = 1; 337e41f4b71Sopenharmony_ci 338e41f4b71Sopenharmony_ci build() { 339e41f4b71Sopenharmony_ci Column() { 340e41f4b71Sopenharmony_ci Text(`incr @LocalStorageLink variable`) 341e41f4b71Sopenharmony_ci // 点击“incr @LocalStorageLink variable”,this.storageLink加1,改变同步回storage,全局变量linkToPropA也会同步改变 342e41f4b71Sopenharmony_ci 343e41f4b71Sopenharmony_ci .onClick(() => { 344e41f4b71Sopenharmony_ci this.storageLink += 1 345e41f4b71Sopenharmony_ci }) 346e41f4b71Sopenharmony_ci 347e41f4b71Sopenharmony_ci // 并不建议在组件内使用全局变量linkToPropA.get(),因为可能会有生命周期不同引起的错误。 348e41f4b71Sopenharmony_ci Text(`@LocalStorageLink: ${this.storageLink} - linkToPropA: ${linkToPropA.get()}`) 349e41f4b71Sopenharmony_ci } 350e41f4b71Sopenharmony_ci } 351e41f4b71Sopenharmony_ci} 352e41f4b71Sopenharmony_ci``` 353e41f4b71Sopenharmony_ci 354e41f4b71Sopenharmony_ci 355e41f4b71Sopenharmony_ci### 兄弟组件之间同步状态变量 356e41f4b71Sopenharmony_ci 357e41f4b71Sopenharmony_ci下面的示例展示了通过\@LocalStorageLink双向同步兄弟组件之间的状态。 358e41f4b71Sopenharmony_ci 359e41f4b71Sopenharmony_ci先看Parent自定义组件中发生的变化: 360e41f4b71Sopenharmony_ci 361e41f4b71Sopenharmony_ci1. 点击“playCount ${this.playCount} dec by 1”,this.playCount减1,修改同步回LocalStorage中,Child组件中的playCountLink绑定的组件会同步刷新; 362e41f4b71Sopenharmony_ci 363e41f4b71Sopenharmony_ci2. 点击“countStorage ${this.playCount} incr by 1”,调用LocalStorage的set接口,更新LocalStorage中“countStorage”对应的属性,Child组件中的playCountLink绑定的组件会同步刷新; 364e41f4b71Sopenharmony_ci 365e41f4b71Sopenharmony_ci3. Text组件“playCount in LocalStorage for debug ${storage.get<number>('countStorage')}”没有同步刷新,因为storage.get<number>('countStorage')返回的是常规变量,常规变量的更新并不会引起Text组件的重新渲染。 366e41f4b71Sopenharmony_ci 367e41f4b71Sopenharmony_ciChild自定义组件中的变化: 368e41f4b71Sopenharmony_ci 369e41f4b71Sopenharmony_ci1. playCountLink的刷新会同步回LocalStorage,并且引起兄弟组件和父组件相应的刷新。 370e41f4b71Sopenharmony_ci 371e41f4b71Sopenharmony_ci```ts 372e41f4b71Sopenharmony_cilet ls: Record<string, number> = { 'countStorage': 1 } 373e41f4b71Sopenharmony_cilet storage: LocalStorage = new LocalStorage(ls); 374e41f4b71Sopenharmony_ci 375e41f4b71Sopenharmony_ci@Component 376e41f4b71Sopenharmony_cistruct Child { 377e41f4b71Sopenharmony_ci // 子组件实例的名字 378e41f4b71Sopenharmony_ci label: string = 'no name'; 379e41f4b71Sopenharmony_ci // 和LocalStorage中“countStorage”的双向绑定数据 380e41f4b71Sopenharmony_ci @LocalStorageLink('countStorage') playCountLink: number = 0; 381e41f4b71Sopenharmony_ci 382e41f4b71Sopenharmony_ci build() { 383e41f4b71Sopenharmony_ci Row() { 384e41f4b71Sopenharmony_ci Text(this.label) 385e41f4b71Sopenharmony_ci .width(50).height(60).fontSize(12) 386e41f4b71Sopenharmony_ci Text(`playCountLink ${this.playCountLink}: inc by 1`) 387e41f4b71Sopenharmony_ci .onClick(() => { 388e41f4b71Sopenharmony_ci this.playCountLink += 1; 389e41f4b71Sopenharmony_ci }) 390e41f4b71Sopenharmony_ci .width(200).height(60).fontSize(12) 391e41f4b71Sopenharmony_ci }.width(300).height(60) 392e41f4b71Sopenharmony_ci } 393e41f4b71Sopenharmony_ci} 394e41f4b71Sopenharmony_ci 395e41f4b71Sopenharmony_ci@Entry(storage) 396e41f4b71Sopenharmony_ci@Component 397e41f4b71Sopenharmony_cistruct Parent { 398e41f4b71Sopenharmony_ci @LocalStorageLink('countStorage') playCount: number = 0; 399e41f4b71Sopenharmony_ci 400e41f4b71Sopenharmony_ci build() { 401e41f4b71Sopenharmony_ci Column() { 402e41f4b71Sopenharmony_ci Row() { 403e41f4b71Sopenharmony_ci Text('Parent') 404e41f4b71Sopenharmony_ci .width(50).height(60).fontSize(12) 405e41f4b71Sopenharmony_ci Text(`playCount ${this.playCount} dec by 1`) 406e41f4b71Sopenharmony_ci .onClick(() => { 407e41f4b71Sopenharmony_ci this.playCount -= 1; 408e41f4b71Sopenharmony_ci }) 409e41f4b71Sopenharmony_ci .width(250).height(60).fontSize(12) 410e41f4b71Sopenharmony_ci }.width(300).height(60) 411e41f4b71Sopenharmony_ci 412e41f4b71Sopenharmony_ci Row() { 413e41f4b71Sopenharmony_ci Text('LocalStorage') 414e41f4b71Sopenharmony_ci .width(50).height(60).fontSize(12) 415e41f4b71Sopenharmony_ci Text(`countStorage ${this.playCount} incr by 1`) 416e41f4b71Sopenharmony_ci .onClick(() => { 417e41f4b71Sopenharmony_ci storage.set<number | undefined>('countStorage', Number(storage.get<number>('countStorage')) + 1); 418e41f4b71Sopenharmony_ci }) 419e41f4b71Sopenharmony_ci .width(250).height(60).fontSize(12) 420e41f4b71Sopenharmony_ci }.width(300).height(60) 421e41f4b71Sopenharmony_ci 422e41f4b71Sopenharmony_ci Child({ label: 'ChildA' }) 423e41f4b71Sopenharmony_ci Child({ label: 'ChildB' }) 424e41f4b71Sopenharmony_ci 425e41f4b71Sopenharmony_ci Text(`playCount in LocalStorage for debug ${storage.get<number>('countStorage')}`) 426e41f4b71Sopenharmony_ci .width(300).height(60).fontSize(12) 427e41f4b71Sopenharmony_ci } 428e41f4b71Sopenharmony_ci } 429e41f4b71Sopenharmony_ci} 430e41f4b71Sopenharmony_ci``` 431e41f4b71Sopenharmony_ci 432e41f4b71Sopenharmony_ci 433e41f4b71Sopenharmony_ci### 将LocalStorage实例从UIAbility共享到一个或多个视图 434e41f4b71Sopenharmony_ci 435e41f4b71Sopenharmony_ci上面的实例中,LocalStorage的实例仅仅在一个\@Entry装饰的组件和其所属的子组件(一个页面)中共享,如果希望其在多个视图中共享,可以在所属UIAbility中创建LocalStorage实例,并调用windowStage.[loadContent](../reference/apis-arkui/js-apis-window.md#loadcontent9)。 436e41f4b71Sopenharmony_ci 437e41f4b71Sopenharmony_ci 438e41f4b71Sopenharmony_ci```ts 439e41f4b71Sopenharmony_ci// EntryAbility.ets 440e41f4b71Sopenharmony_ciimport { UIAbility } from '@kit.AbilityKit'; 441e41f4b71Sopenharmony_ciimport { window } from '@kit.ArkUI'; 442e41f4b71Sopenharmony_ci 443e41f4b71Sopenharmony_ciexport default class EntryAbility extends UIAbility { 444e41f4b71Sopenharmony_cipara:Record<string, number> = { 'PropA': 47 }; 445e41f4b71Sopenharmony_cistorage: LocalStorage = new LocalStorage(this.para); 446e41f4b71Sopenharmony_ci 447e41f4b71Sopenharmony_cionWindowStageCreate(windowStage: window.WindowStage) { 448e41f4b71Sopenharmony_ciwindowStage.loadContent('pages/Index', this.storage); 449e41f4b71Sopenharmony_ci} 450e41f4b71Sopenharmony_ci} 451e41f4b71Sopenharmony_ci``` 452e41f4b71Sopenharmony_ci> **说明:** 453e41f4b71Sopenharmony_ci> 454e41f4b71Sopenharmony_ci> 在UI页面通过getShared接口获取通过loadContent共享的LocalStorage实例。 455e41f4b71Sopenharmony_ci> 456e41f4b71Sopenharmony_ci> LocalStorage.getShared()只在模拟器或者实机上才有效,在Previewer预览器中使用不生效。 457e41f4b71Sopenharmony_ci 458e41f4b71Sopenharmony_ci 459e41f4b71Sopenharmony_ci在下面的用例中,Index页面中的propA通过getShared()方法获取到共享的LocalStorage实例。点击Button跳转到Page页面,点击Change propA改变propA的值,back回Index页面后,页面中propA的值也同步修改。 460e41f4b71Sopenharmony_ci```ts 461e41f4b71Sopenharmony_ci// index.ets 462e41f4b71Sopenharmony_ciimport { router } from '@kit.ArkUI'; 463e41f4b71Sopenharmony_ci 464e41f4b71Sopenharmony_ci// 通过getShared接口获取stage共享的LocalStorage实例 465e41f4b71Sopenharmony_cilet storage = LocalStorage.getShared() 466e41f4b71Sopenharmony_ci 467e41f4b71Sopenharmony_ci@Entry(storage) 468e41f4b71Sopenharmony_ci@Component 469e41f4b71Sopenharmony_cistruct Index { 470e41f4b71Sopenharmony_ci // can access LocalStorage instance using 471e41f4b71Sopenharmony_ci // @LocalStorageLink/Prop decorated variables 472e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') propA: number = 1; 473e41f4b71Sopenharmony_ci 474e41f4b71Sopenharmony_ci build() { 475e41f4b71Sopenharmony_ci Row() { 476e41f4b71Sopenharmony_ci Column() { 477e41f4b71Sopenharmony_ci Text(`${this.propA}`) 478e41f4b71Sopenharmony_ci .fontSize(50) 479e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 480e41f4b71Sopenharmony_ci Button("To Page") 481e41f4b71Sopenharmony_ci .onClick(() => { 482e41f4b71Sopenharmony_ci this.getUIContext().getRouter().pushUrl({ 483e41f4b71Sopenharmony_ci url: 'pages/Page' 484e41f4b71Sopenharmony_ci }) 485e41f4b71Sopenharmony_ci }) 486e41f4b71Sopenharmony_ci } 487e41f4b71Sopenharmony_ci .width('100%') 488e41f4b71Sopenharmony_ci } 489e41f4b71Sopenharmony_ci .height('100%') 490e41f4b71Sopenharmony_ci } 491e41f4b71Sopenharmony_ci} 492e41f4b71Sopenharmony_ci``` 493e41f4b71Sopenharmony_ci 494e41f4b71Sopenharmony_ci```ts 495e41f4b71Sopenharmony_ci// Page.ets 496e41f4b71Sopenharmony_ciimport { router } from '@kit.ArkUI'; 497e41f4b71Sopenharmony_ci 498e41f4b71Sopenharmony_cilet storage = LocalStorage.getShared() 499e41f4b71Sopenharmony_ci 500e41f4b71Sopenharmony_ci@Entry(storage) 501e41f4b71Sopenharmony_ci@Component 502e41f4b71Sopenharmony_cistruct Page { 503e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') propA: number = 2; 504e41f4b71Sopenharmony_ci 505e41f4b71Sopenharmony_ci build() { 506e41f4b71Sopenharmony_ci Row() { 507e41f4b71Sopenharmony_ci Column() { 508e41f4b71Sopenharmony_ci Text(`${this.propA}`) 509e41f4b71Sopenharmony_ci .fontSize(50) 510e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 511e41f4b71Sopenharmony_ci 512e41f4b71Sopenharmony_ci Button("Change propA") 513e41f4b71Sopenharmony_ci .onClick(() => { 514e41f4b71Sopenharmony_ci this.propA = 100; 515e41f4b71Sopenharmony_ci }) 516e41f4b71Sopenharmony_ci 517e41f4b71Sopenharmony_ci Button("Back Index") 518e41f4b71Sopenharmony_ci .onClick(() => { 519e41f4b71Sopenharmony_ci this.getUIContext().getRouter().back() 520e41f4b71Sopenharmony_ci }) 521e41f4b71Sopenharmony_ci } 522e41f4b71Sopenharmony_ci .width('100%') 523e41f4b71Sopenharmony_ci } 524e41f4b71Sopenharmony_ci } 525e41f4b71Sopenharmony_ci} 526e41f4b71Sopenharmony_ci``` 527e41f4b71Sopenharmony_ci 528e41f4b71Sopenharmony_ci> **说明:** 529e41f4b71Sopenharmony_ci> 530e41f4b71Sopenharmony_ci> 对于开发者更建议使用这个方式来构建LocalStorage的实例,并且在创建LocalStorage实例的时候就写入默认值,因为默认值可以作为运行异常的备份,也可以用作页面的单元测试。 531e41f4b71Sopenharmony_ci 532e41f4b71Sopenharmony_ci 533e41f4b71Sopenharmony_ci### 自定义组件接收LocalStorage实例 534e41f4b71Sopenharmony_ci 535e41f4b71Sopenharmony_ci除了根节点可通过@Entry来接收LocalStorage实例,自定义组件(子节点)也可以通过构造参数来传递LocalStorage实例。 536e41f4b71Sopenharmony_ci 537e41f4b71Sopenharmony_ci本示例以\@LocalStorageLink为例,展示了: 538e41f4b71Sopenharmony_ci 539e41f4b71Sopenharmony_ci- 父组件中的Text,显示LocalStorage实例localStorage1中PropA的值为“PropA”。 540e41f4b71Sopenharmony_ci 541e41f4b71Sopenharmony_ci- Child组件中,Text绑定的PropB,显示LocalStorage实例localStorage2中PropB的值为“PropB”。 542e41f4b71Sopenharmony_ci 543e41f4b71Sopenharmony_ci> **说明:** 544e41f4b71Sopenharmony_ci> 545e41f4b71Sopenharmony_ci> 从API version 12开始,自定义组件支持接收LocalStorage实例。 546e41f4b71Sopenharmony_ci> 当自定义组件作为子节点,定义了成员属性时,LocalStorage实例必须要放在第二个参数位置传递,否则会报类型不匹配的编译问题。 547e41f4b71Sopenharmony_ci> 当在自定义组件中定义了属性时,暂时不支持只有一个LocalStorage实例作为入参。如果没定义属性,可以只传入一个LocalStorage实例作为入参。 548e41f4b71Sopenharmony_ci> 如果定义的属性不需要从父组件初始化变量,则第一个参数需要传{}。 549e41f4b71Sopenharmony_ci> 作为构造参数传给子组件的LocalStorage实例在初始化时就会被决定,可以通过@LocalStorageLink或者LocalStorage的API修改LocalStorage实例中保存的属性值,但LocalStorage实例自身不能被动态修改。 550e41f4b71Sopenharmony_ci 551e41f4b71Sopenharmony_ci```ts 552e41f4b71Sopenharmony_cilet localStorage1: LocalStorage = new LocalStorage(); 553e41f4b71Sopenharmony_cilocalStorage1.setOrCreate('PropA', 'PropA'); 554e41f4b71Sopenharmony_ci 555e41f4b71Sopenharmony_cilet localStorage2: LocalStorage = new LocalStorage(); 556e41f4b71Sopenharmony_cilocalStorage2.setOrCreate('PropB', 'PropB'); 557e41f4b71Sopenharmony_ci 558e41f4b71Sopenharmony_ci@Entry(localStorage1) 559e41f4b71Sopenharmony_ci@Component 560e41f4b71Sopenharmony_cistruct Index { 561e41f4b71Sopenharmony_ci // 'PropA',和localStorage1中'PropA'的双向同步 562e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') PropA: string = 'Hello World'; 563e41f4b71Sopenharmony_ci @State count: number = 0; 564e41f4b71Sopenharmony_ci 565e41f4b71Sopenharmony_ci build() { 566e41f4b71Sopenharmony_ci Row() { 567e41f4b71Sopenharmony_ci Column() { 568e41f4b71Sopenharmony_ci Text(this.PropA) 569e41f4b71Sopenharmony_ci .fontSize(50) 570e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 571e41f4b71Sopenharmony_ci // 使用LocalStorage 实例localStorage2 572e41f4b71Sopenharmony_ci Child({ count: this.count }, localStorage2) 573e41f4b71Sopenharmony_ci } 574e41f4b71Sopenharmony_ci .width('100%') 575e41f4b71Sopenharmony_ci } 576e41f4b71Sopenharmony_ci .height('100%') 577e41f4b71Sopenharmony_ci } 578e41f4b71Sopenharmony_ci} 579e41f4b71Sopenharmony_ci 580e41f4b71Sopenharmony_ci 581e41f4b71Sopenharmony_ci@Component 582e41f4b71Sopenharmony_cistruct Child { 583e41f4b71Sopenharmony_ci @Link count: number; 584e41f4b71Sopenharmony_ci // 'Hello World',和localStorage2中'PropB'的双向同步,localStorage2中没有'PropB',则使用默认值'Hello World' 585e41f4b71Sopenharmony_ci @LocalStorageLink('PropB') PropB: string = 'Hello World'; 586e41f4b71Sopenharmony_ci 587e41f4b71Sopenharmony_ci build() { 588e41f4b71Sopenharmony_ci Text(this.PropB) 589e41f4b71Sopenharmony_ci .fontSize(50) 590e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 591e41f4b71Sopenharmony_ci } 592e41f4b71Sopenharmony_ci} 593e41f4b71Sopenharmony_ci``` 594e41f4b71Sopenharmony_ci 595e41f4b71Sopenharmony_ci1. 当自定义组件没有定义属性时,可以只传入一个LocalStorage实例作为入参。 596e41f4b71Sopenharmony_ci 597e41f4b71Sopenharmony_ci```ts 598e41f4b71Sopenharmony_cilet localStorage1: LocalStorage = new LocalStorage(); 599e41f4b71Sopenharmony_cilocalStorage1.setOrCreate('PropA', 'PropA'); 600e41f4b71Sopenharmony_ci 601e41f4b71Sopenharmony_cilet localStorage2: LocalStorage = new LocalStorage(); 602e41f4b71Sopenharmony_cilocalStorage2.setOrCreate('PropB', 'PropB'); 603e41f4b71Sopenharmony_ci 604e41f4b71Sopenharmony_ci@Entry(localStorage1) 605e41f4b71Sopenharmony_ci@Component 606e41f4b71Sopenharmony_cistruct Index { 607e41f4b71Sopenharmony_ci // 'PropA',和localStorage1中'PropA'的双向同步 608e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') PropA: string = 'Hello World'; 609e41f4b71Sopenharmony_ci @State count: number = 0; 610e41f4b71Sopenharmony_ci 611e41f4b71Sopenharmony_ci build() { 612e41f4b71Sopenharmony_ci Row() { 613e41f4b71Sopenharmony_ci Column() { 614e41f4b71Sopenharmony_ci Text(this.PropA) 615e41f4b71Sopenharmony_ci .fontSize(50) 616e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 617e41f4b71Sopenharmony_ci // 使用LocalStorage 实例localStorage2 618e41f4b71Sopenharmony_ci Child(localStorage2) 619e41f4b71Sopenharmony_ci } 620e41f4b71Sopenharmony_ci .width('100%') 621e41f4b71Sopenharmony_ci } 622e41f4b71Sopenharmony_ci .height('100%') 623e41f4b71Sopenharmony_ci } 624e41f4b71Sopenharmony_ci} 625e41f4b71Sopenharmony_ci 626e41f4b71Sopenharmony_ci 627e41f4b71Sopenharmony_ci@Component 628e41f4b71Sopenharmony_cistruct Child { 629e41f4b71Sopenharmony_ci build() { 630e41f4b71Sopenharmony_ci Text("hello") 631e41f4b71Sopenharmony_ci .fontSize(50) 632e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 633e41f4b71Sopenharmony_ci } 634e41f4b71Sopenharmony_ci} 635e41f4b71Sopenharmony_ci``` 636e41f4b71Sopenharmony_ci 637e41f4b71Sopenharmony_ci2. 当定义的属性不需要从父组件初始化变量时,第一个参数需要传{}。 638e41f4b71Sopenharmony_ci 639e41f4b71Sopenharmony_ci```ts 640e41f4b71Sopenharmony_cilet localStorage1: LocalStorage = new LocalStorage(); 641e41f4b71Sopenharmony_cilocalStorage1.setOrCreate('PropA', 'PropA'); 642e41f4b71Sopenharmony_ci 643e41f4b71Sopenharmony_cilet localStorage2: LocalStorage = new LocalStorage(); 644e41f4b71Sopenharmony_cilocalStorage2.setOrCreate('PropB', 'PropB'); 645e41f4b71Sopenharmony_ci 646e41f4b71Sopenharmony_ci@Entry(localStorage1) 647e41f4b71Sopenharmony_ci@Component 648e41f4b71Sopenharmony_cistruct Index { 649e41f4b71Sopenharmony_ci // 'PropA',和localStorage1中'PropA'的双向同步 650e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') PropA: string = 'Hello World'; 651e41f4b71Sopenharmony_ci @State count: number = 0; 652e41f4b71Sopenharmony_ci 653e41f4b71Sopenharmony_ci build() { 654e41f4b71Sopenharmony_ci Row() { 655e41f4b71Sopenharmony_ci Column() { 656e41f4b71Sopenharmony_ci Text(this.PropA) 657e41f4b71Sopenharmony_ci .fontSize(50) 658e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 659e41f4b71Sopenharmony_ci // 使用LocalStorage 实例localStorage2 660e41f4b71Sopenharmony_ci Child({}, localStorage2) 661e41f4b71Sopenharmony_ci } 662e41f4b71Sopenharmony_ci .width('100%') 663e41f4b71Sopenharmony_ci } 664e41f4b71Sopenharmony_ci .height('100%') 665e41f4b71Sopenharmony_ci } 666e41f4b71Sopenharmony_ci} 667e41f4b71Sopenharmony_ci 668e41f4b71Sopenharmony_ci 669e41f4b71Sopenharmony_ci@Component 670e41f4b71Sopenharmony_cistruct Child { 671e41f4b71Sopenharmony_ci @State count: number = 5; 672e41f4b71Sopenharmony_ci // 'Hello World',和localStorage2中'PropB'的双向同步,localStorage2中没有'PropB',则使用默认值'Hello World' 673e41f4b71Sopenharmony_ci @LocalStorageLink('PropB') PropB: string = 'Hello World'; 674e41f4b71Sopenharmony_ci 675e41f4b71Sopenharmony_ci build() { 676e41f4b71Sopenharmony_ci Text(this.PropB) 677e41f4b71Sopenharmony_ci .fontSize(50) 678e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 679e41f4b71Sopenharmony_ci } 680e41f4b71Sopenharmony_ci} 681e41f4b71Sopenharmony_ci``` 682e41f4b71Sopenharmony_ci 683e41f4b71Sopenharmony_ci 684e41f4b71Sopenharmony_ci### Navigation组件和LocalStorage联合使用 685e41f4b71Sopenharmony_ci 686e41f4b71Sopenharmony_ci可以通过传递不同的LocalStorage实例给自定义组件,从而实现在navigation跳转到不同的页面时,绑定不同的LocalStorage实例,显示对应绑定的值。 687e41f4b71Sopenharmony_ci 688e41f4b71Sopenharmony_ci本示例以\@LocalStorageLink为例,展示了: 689e41f4b71Sopenharmony_ci 690e41f4b71Sopenharmony_ci- 点击父组件中的Button "Next Page",创建并跳转到name为"pageOne"的子页面,Text显示信息为LocalStorage实例localStorageA中绑定的PropA的值,为"PropA"。 691e41f4b71Sopenharmony_ci 692e41f4b71Sopenharmony_ci- 继续点击页面上的Button "Next Page",创建并跳转到name为"pageTwo"的子页面,Text显示信息为LocalStorage实例localStorageB中绑定的PropB的值,为"PropB"。 693e41f4b71Sopenharmony_ci 694e41f4b71Sopenharmony_ci- 继续点击页面上的Button "Next Page",创建并跳转到name为"pageTree"的子页面,Text显示信息为LocalStorage实例localStorageC中绑定的PropC的值,为"PropC"。 695e41f4b71Sopenharmony_ci 696e41f4b71Sopenharmony_ci- 继续点击页面上的Button "Next Page",创建并跳转到name为"pageOne"的子页面,Text显示信息为LocalStorage实例localStorageA中绑定的PropA的值,为"PropA"。 697e41f4b71Sopenharmony_ci 698e41f4b71Sopenharmony_ci- NavigationContentMsgStack自定义组件中的Text组件,共享对应自定义组件树上LocalStorage实例绑定的PropA的值。 699e41f4b71Sopenharmony_ci 700e41f4b71Sopenharmony_ci 701e41f4b71Sopenharmony_ci```ts 702e41f4b71Sopenharmony_cilet localStorageA: LocalStorage = new LocalStorage(); 703e41f4b71Sopenharmony_cilocalStorageA.setOrCreate('PropA', 'PropA'); 704e41f4b71Sopenharmony_ci 705e41f4b71Sopenharmony_cilet localStorageB: LocalStorage = new LocalStorage(); 706e41f4b71Sopenharmony_cilocalStorageB.setOrCreate('PropB', 'PropB'); 707e41f4b71Sopenharmony_ci 708e41f4b71Sopenharmony_cilet localStorageC: LocalStorage = new LocalStorage(); 709e41f4b71Sopenharmony_cilocalStorageC.setOrCreate('PropC', 'PropC'); 710e41f4b71Sopenharmony_ci 711e41f4b71Sopenharmony_ci@Entry 712e41f4b71Sopenharmony_ci@Component 713e41f4b71Sopenharmony_cistruct MyNavigationTestStack { 714e41f4b71Sopenharmony_ci @Provide('pageInfo') pageInfo: NavPathStack = new NavPathStack(); 715e41f4b71Sopenharmony_ci 716e41f4b71Sopenharmony_ci @Builder 717e41f4b71Sopenharmony_ci PageMap(name: string) { 718e41f4b71Sopenharmony_ci if (name === 'pageOne') { 719e41f4b71Sopenharmony_ci // 传递不同的LocalStorage实例 720e41f4b71Sopenharmony_ci pageOneStack({}, localStorageA) 721e41f4b71Sopenharmony_ci } else if (name === 'pageTwo') { 722e41f4b71Sopenharmony_ci pageTwoStack({}, localStorageB) 723e41f4b71Sopenharmony_ci } else if (name === 'pageThree') { 724e41f4b71Sopenharmony_ci pageThreeStack({}, localStorageC) 725e41f4b71Sopenharmony_ci } 726e41f4b71Sopenharmony_ci } 727e41f4b71Sopenharmony_ci 728e41f4b71Sopenharmony_ci build() { 729e41f4b71Sopenharmony_ci Column({ space: 5 }) { 730e41f4b71Sopenharmony_ci Navigation(this.pageInfo) { 731e41f4b71Sopenharmony_ci Column() { 732e41f4b71Sopenharmony_ci Button('Next Page', { stateEffect: true, type: ButtonType.Capsule }) 733e41f4b71Sopenharmony_ci .width('80%') 734e41f4b71Sopenharmony_ci .height(40) 735e41f4b71Sopenharmony_ci .margin(20) 736e41f4b71Sopenharmony_ci .onClick(() => { 737e41f4b71Sopenharmony_ci this.pageInfo.pushPath({ name: 'pageOne' }); //将name指定的NavDestination页面信息入栈 738e41f4b71Sopenharmony_ci }) 739e41f4b71Sopenharmony_ci } 740e41f4b71Sopenharmony_ci }.title('NavIndex') 741e41f4b71Sopenharmony_ci .navDestination(this.PageMap) 742e41f4b71Sopenharmony_ci .mode(NavigationMode.Stack) 743e41f4b71Sopenharmony_ci .borderWidth(1) 744e41f4b71Sopenharmony_ci } 745e41f4b71Sopenharmony_ci } 746e41f4b71Sopenharmony_ci} 747e41f4b71Sopenharmony_ci 748e41f4b71Sopenharmony_ci@Component 749e41f4b71Sopenharmony_cistruct pageOneStack { 750e41f4b71Sopenharmony_ci @Consume('pageInfo') pageInfo: NavPathStack; 751e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') PropA: string = 'Hello World'; 752e41f4b71Sopenharmony_ci 753e41f4b71Sopenharmony_ci build() { 754e41f4b71Sopenharmony_ci NavDestination() { 755e41f4b71Sopenharmony_ci Column() { 756e41f4b71Sopenharmony_ci NavigationContentMsgStack() 757e41f4b71Sopenharmony_ci // 显示绑定的LocalStorage中PropA的值'PropA' 758e41f4b71Sopenharmony_ci Text(`${this.PropA}`) 759e41f4b71Sopenharmony_ci Button('Next Page', { stateEffect: true, type: ButtonType.Capsule }) 760e41f4b71Sopenharmony_ci .width('80%') 761e41f4b71Sopenharmony_ci .height(40) 762e41f4b71Sopenharmony_ci .margin(20) 763e41f4b71Sopenharmony_ci .onClick(() => { 764e41f4b71Sopenharmony_ci this.pageInfo.pushPathByName('pageTwo', null); 765e41f4b71Sopenharmony_ci }) 766e41f4b71Sopenharmony_ci }.width('100%').height('100%') 767e41f4b71Sopenharmony_ci }.title('pageOne') 768e41f4b71Sopenharmony_ci .onBackPressed(() => { 769e41f4b71Sopenharmony_ci this.pageInfo.pop(); 770e41f4b71Sopenharmony_ci return true; 771e41f4b71Sopenharmony_ci }) 772e41f4b71Sopenharmony_ci } 773e41f4b71Sopenharmony_ci} 774e41f4b71Sopenharmony_ci 775e41f4b71Sopenharmony_ci@Component 776e41f4b71Sopenharmony_cistruct pageTwoStack { 777e41f4b71Sopenharmony_ci @Consume('pageInfo') pageInfo: NavPathStack; 778e41f4b71Sopenharmony_ci @LocalStorageLink('PropB') PropB: string = 'Hello World'; 779e41f4b71Sopenharmony_ci 780e41f4b71Sopenharmony_ci build() { 781e41f4b71Sopenharmony_ci NavDestination() { 782e41f4b71Sopenharmony_ci Column() { 783e41f4b71Sopenharmony_ci NavigationContentMsgStack() 784e41f4b71Sopenharmony_ci // 绑定的LocalStorage中没有PropA,显示本地初始化的值 'Hello World' 785e41f4b71Sopenharmony_ci Text(`${this.PropB}`) 786e41f4b71Sopenharmony_ci Button('Next Page', { stateEffect: true, type: ButtonType.Capsule }) 787e41f4b71Sopenharmony_ci .width('80%') 788e41f4b71Sopenharmony_ci .height(40) 789e41f4b71Sopenharmony_ci .margin(20) 790e41f4b71Sopenharmony_ci .onClick(() => { 791e41f4b71Sopenharmony_ci this.pageInfo.pushPathByName('pageThree', null); 792e41f4b71Sopenharmony_ci }) 793e41f4b71Sopenharmony_ci 794e41f4b71Sopenharmony_ci }.width('100%').height('100%') 795e41f4b71Sopenharmony_ci }.title('pageTwo') 796e41f4b71Sopenharmony_ci .onBackPressed(() => { 797e41f4b71Sopenharmony_ci this.pageInfo.pop(); 798e41f4b71Sopenharmony_ci return true; 799e41f4b71Sopenharmony_ci }) 800e41f4b71Sopenharmony_ci } 801e41f4b71Sopenharmony_ci} 802e41f4b71Sopenharmony_ci 803e41f4b71Sopenharmony_ci@Component 804e41f4b71Sopenharmony_cistruct pageThreeStack { 805e41f4b71Sopenharmony_ci @Consume('pageInfo') pageInfo: NavPathStack; 806e41f4b71Sopenharmony_ci @LocalStorageLink('PropC') PropC: string = 'pageThreeStack'; 807e41f4b71Sopenharmony_ci 808e41f4b71Sopenharmony_ci build() { 809e41f4b71Sopenharmony_ci NavDestination() { 810e41f4b71Sopenharmony_ci Column() { 811e41f4b71Sopenharmony_ci NavigationContentMsgStack() 812e41f4b71Sopenharmony_ci 813e41f4b71Sopenharmony_ci // 绑定的LocalStorage中没有PropA,显示本地初始化的值 'pageThreeStack' 814e41f4b71Sopenharmony_ci Text(`${this.PropC}`) 815e41f4b71Sopenharmony_ci Button('Next Page', { stateEffect: true, type: ButtonType.Capsule }) 816e41f4b71Sopenharmony_ci .width('80%') 817e41f4b71Sopenharmony_ci .height(40) 818e41f4b71Sopenharmony_ci .margin(20) 819e41f4b71Sopenharmony_ci .onClick(() => { 820e41f4b71Sopenharmony_ci this.pageInfo.pushPathByName('pageOne', null); 821e41f4b71Sopenharmony_ci }) 822e41f4b71Sopenharmony_ci 823e41f4b71Sopenharmony_ci }.width('100%').height('100%') 824e41f4b71Sopenharmony_ci }.title('pageThree') 825e41f4b71Sopenharmony_ci .onBackPressed(() => { 826e41f4b71Sopenharmony_ci this.pageInfo.pop(); 827e41f4b71Sopenharmony_ci return true; 828e41f4b71Sopenharmony_ci }) 829e41f4b71Sopenharmony_ci } 830e41f4b71Sopenharmony_ci} 831e41f4b71Sopenharmony_ci 832e41f4b71Sopenharmony_ci@Component 833e41f4b71Sopenharmony_cistruct NavigationContentMsgStack { 834e41f4b71Sopenharmony_ci @LocalStorageLink('PropA') PropA: string = 'Hello'; 835e41f4b71Sopenharmony_ci 836e41f4b71Sopenharmony_ci build() { 837e41f4b71Sopenharmony_ci Column() { 838e41f4b71Sopenharmony_ci Text(`${this.PropA}`) 839e41f4b71Sopenharmony_ci .fontSize(30) 840e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 841e41f4b71Sopenharmony_ci } 842e41f4b71Sopenharmony_ci } 843e41f4b71Sopenharmony_ci} 844e41f4b71Sopenharmony_ci``` 845e41f4b71Sopenharmony_ci 846e41f4b71Sopenharmony_ci 847e41f4b71Sopenharmony_ci### LocalStorage支持联合类型 848e41f4b71Sopenharmony_ci 849e41f4b71Sopenharmony_ci在下面的示例中,变量A的类型为number | null,变量B的类型为number | undefined。Text组件初始化分别显示为null和undefined,点击切换为数字,再次点击切换回null和undefined。 850e41f4b71Sopenharmony_ci 851e41f4b71Sopenharmony_ci```ts 852e41f4b71Sopenharmony_ci@Component 853e41f4b71Sopenharmony_cistruct LocalStorLink { 854e41f4b71Sopenharmony_ci @LocalStorageLink("AA") A: number | null = null; 855e41f4b71Sopenharmony_ci @LocalStorageLink("BB") B: number | undefined = undefined; 856e41f4b71Sopenharmony_ci 857e41f4b71Sopenharmony_ci build() { 858e41f4b71Sopenharmony_ci Column() { 859e41f4b71Sopenharmony_ci Text("@LocalStorageLink接口初始化,@LocalStorageLink取值") 860e41f4b71Sopenharmony_ci Text(this.A + "").fontSize(20).onClick(() => { 861e41f4b71Sopenharmony_ci this.A ? this.A = null : this.A = 1; 862e41f4b71Sopenharmony_ci }) 863e41f4b71Sopenharmony_ci Text(this.B + "").fontSize(20).onClick(() => { 864e41f4b71Sopenharmony_ci this.B ? this.B = undefined : this.B = 1; 865e41f4b71Sopenharmony_ci }) 866e41f4b71Sopenharmony_ci } 867e41f4b71Sopenharmony_ci .borderWidth(3).borderColor(Color.Green) 868e41f4b71Sopenharmony_ci 869e41f4b71Sopenharmony_ci } 870e41f4b71Sopenharmony_ci} 871e41f4b71Sopenharmony_ci 872e41f4b71Sopenharmony_ci@Component 873e41f4b71Sopenharmony_cistruct LocalStorProp { 874e41f4b71Sopenharmony_ci @LocalStorageProp("AAA") A: number | null = null; 875e41f4b71Sopenharmony_ci @LocalStorageProp("BBB") B: number | undefined = undefined; 876e41f4b71Sopenharmony_ci 877e41f4b71Sopenharmony_ci build() { 878e41f4b71Sopenharmony_ci Column() { 879e41f4b71Sopenharmony_ci Text("@LocalStorageProp接口初始化,@LocalStorageProp取值") 880e41f4b71Sopenharmony_ci Text(this.A + "").fontSize(20).onClick(() => { 881e41f4b71Sopenharmony_ci this.A ? this.A = null : this.A = 1; 882e41f4b71Sopenharmony_ci }) 883e41f4b71Sopenharmony_ci Text(this.B + "").fontSize(20).onClick(() => { 884e41f4b71Sopenharmony_ci this.B ? this.B = undefined : this.B = 1; 885e41f4b71Sopenharmony_ci }) 886e41f4b71Sopenharmony_ci } 887e41f4b71Sopenharmony_ci .borderWidth(3).borderColor(Color.Yellow) 888e41f4b71Sopenharmony_ci 889e41f4b71Sopenharmony_ci } 890e41f4b71Sopenharmony_ci} 891e41f4b71Sopenharmony_ci 892e41f4b71Sopenharmony_cilet storage1: LocalStorage = new LocalStorage(); 893e41f4b71Sopenharmony_ci 894e41f4b71Sopenharmony_ci@Entry(storage1) 895e41f4b71Sopenharmony_ci@Component 896e41f4b71Sopenharmony_cistruct TestCase3 { 897e41f4b71Sopenharmony_ci build() { 898e41f4b71Sopenharmony_ci Row() { 899e41f4b71Sopenharmony_ci Column() { 900e41f4b71Sopenharmony_ci LocalStorLink() 901e41f4b71Sopenharmony_ci LocalStorProp() 902e41f4b71Sopenharmony_ci } 903e41f4b71Sopenharmony_ci .width('100%') 904e41f4b71Sopenharmony_ci } 905e41f4b71Sopenharmony_ci .height('100%') 906e41f4b71Sopenharmony_ci } 907e41f4b71Sopenharmony_ci} 908e41f4b71Sopenharmony_ci``` 909e41f4b71Sopenharmony_ci 910e41f4b71Sopenharmony_ci 911e41f4b71Sopenharmony_ci### 装饰Date类型变量 912e41f4b71Sopenharmony_ci 913e41f4b71Sopenharmony_ci> **说明:** 914e41f4b71Sopenharmony_ci> 915e41f4b71Sopenharmony_ci> 从API version 12开始,LocalStorage支持Date类型。 916e41f4b71Sopenharmony_ci 917e41f4b71Sopenharmony_ci在下面的示例中,@LocalStorageLink装饰的selectedDate类型为Date,点击Button改变selectedDate的值,视图会随之刷新。 918e41f4b71Sopenharmony_ci 919e41f4b71Sopenharmony_ci```ts 920e41f4b71Sopenharmony_ci@Entry 921e41f4b71Sopenharmony_ci@Component 922e41f4b71Sopenharmony_cistruct LocalDateSample { 923e41f4b71Sopenharmony_ci @LocalStorageLink("date") selectedDate: Date = new Date('2021-08-08'); 924e41f4b71Sopenharmony_ci 925e41f4b71Sopenharmony_ci build() { 926e41f4b71Sopenharmony_ci Column() { 927e41f4b71Sopenharmony_ci Button('set selectedDate to 2023-07-08') 928e41f4b71Sopenharmony_ci .margin(10) 929e41f4b71Sopenharmony_ci .onClick(() => { 930e41f4b71Sopenharmony_ci this.selectedDate = new Date('2023-07-08'); 931e41f4b71Sopenharmony_ci }) 932e41f4b71Sopenharmony_ci Button('increase the year by 1') 933e41f4b71Sopenharmony_ci .margin(10) 934e41f4b71Sopenharmony_ci .onClick(() => { 935e41f4b71Sopenharmony_ci this.selectedDate.setFullYear(this.selectedDate.getFullYear() + 1); 936e41f4b71Sopenharmony_ci }) 937e41f4b71Sopenharmony_ci Button('increase the month by 1') 938e41f4b71Sopenharmony_ci .margin(10) 939e41f4b71Sopenharmony_ci .onClick(() => { 940e41f4b71Sopenharmony_ci this.selectedDate.setMonth(this.selectedDate.getMonth() + 1); 941e41f4b71Sopenharmony_ci }) 942e41f4b71Sopenharmony_ci Button('increase the day by 1') 943e41f4b71Sopenharmony_ci .margin(10) 944e41f4b71Sopenharmony_ci .onClick(() => { 945e41f4b71Sopenharmony_ci this.selectedDate.setDate(this.selectedDate.getDate() + 1); 946e41f4b71Sopenharmony_ci }) 947e41f4b71Sopenharmony_ci DatePicker({ 948e41f4b71Sopenharmony_ci start: new Date('1970-1-1'), 949e41f4b71Sopenharmony_ci end: new Date('2100-1-1'), 950e41f4b71Sopenharmony_ci selected: $$this.selectedDate 951e41f4b71Sopenharmony_ci }) 952e41f4b71Sopenharmony_ci }.width('100%') 953e41f4b71Sopenharmony_ci } 954e41f4b71Sopenharmony_ci} 955e41f4b71Sopenharmony_ci``` 956e41f4b71Sopenharmony_ci 957e41f4b71Sopenharmony_ci 958e41f4b71Sopenharmony_ci### 装饰Map类型变量 959e41f4b71Sopenharmony_ci 960e41f4b71Sopenharmony_ci> **说明:** 961e41f4b71Sopenharmony_ci> 962e41f4b71Sopenharmony_ci> 从API version 12开始,LocalStorage支持Map类型。 963e41f4b71Sopenharmony_ci 964e41f4b71Sopenharmony_ci在下面的示例中,@LocalStorageLink装饰的message类型为Map\<number, string\>,点击Button改变message的值,视图会随之刷新。 965e41f4b71Sopenharmony_ci 966e41f4b71Sopenharmony_ci```ts 967e41f4b71Sopenharmony_ci@Entry 968e41f4b71Sopenharmony_ci@Component 969e41f4b71Sopenharmony_cistruct LocalMapSample { 970e41f4b71Sopenharmony_ci @LocalStorageLink("map") message: Map<number, string> = new Map([[0, "a"], [1, "b"], [3, "c"]]); 971e41f4b71Sopenharmony_ci 972e41f4b71Sopenharmony_ci build() { 973e41f4b71Sopenharmony_ci Row() { 974e41f4b71Sopenharmony_ci Column() { 975e41f4b71Sopenharmony_ci ForEach(Array.from(this.message.entries()), (item: [number, string]) => { 976e41f4b71Sopenharmony_ci Text(`${item[0]}`).fontSize(30) 977e41f4b71Sopenharmony_ci Text(`${item[1]}`).fontSize(30) 978e41f4b71Sopenharmony_ci Divider() 979e41f4b71Sopenharmony_ci }) 980e41f4b71Sopenharmony_ci Button('init map').onClick(() => { 981e41f4b71Sopenharmony_ci this.message = new Map([[0, "a"], [1, "b"], [3, "c"]]); 982e41f4b71Sopenharmony_ci }) 983e41f4b71Sopenharmony_ci Button('set new one').onClick(() => { 984e41f4b71Sopenharmony_ci this.message.set(4, "d"); 985e41f4b71Sopenharmony_ci }) 986e41f4b71Sopenharmony_ci Button('clear').onClick(() => { 987e41f4b71Sopenharmony_ci this.message.clear(); 988e41f4b71Sopenharmony_ci }) 989e41f4b71Sopenharmony_ci Button('replace the existing one').onClick(() => { 990e41f4b71Sopenharmony_ci this.message.set(0, "aa"); 991e41f4b71Sopenharmony_ci }) 992e41f4b71Sopenharmony_ci Button('delete the existing one').onClick(() => { 993e41f4b71Sopenharmony_ci this.message.delete(0); 994e41f4b71Sopenharmony_ci }) 995e41f4b71Sopenharmony_ci } 996e41f4b71Sopenharmony_ci .width('100%') 997e41f4b71Sopenharmony_ci } 998e41f4b71Sopenharmony_ci .height('100%') 999e41f4b71Sopenharmony_ci } 1000e41f4b71Sopenharmony_ci} 1001e41f4b71Sopenharmony_ci``` 1002e41f4b71Sopenharmony_ci 1003e41f4b71Sopenharmony_ci 1004e41f4b71Sopenharmony_ci### 装饰Set类型变量 1005e41f4b71Sopenharmony_ci 1006e41f4b71Sopenharmony_ci> **说明:** 1007e41f4b71Sopenharmony_ci> 1008e41f4b71Sopenharmony_ci> 从API version 12开始,LocalStorage支持Set类型。 1009e41f4b71Sopenharmony_ci 1010e41f4b71Sopenharmony_ci在下面的示例中,@LocalStorageLink装饰的memberSet类型为Set\<number\>,点击Button改变memberSet的值,视图会随之刷新。 1011e41f4b71Sopenharmony_ci 1012e41f4b71Sopenharmony_ci```ts 1013e41f4b71Sopenharmony_ci@Entry 1014e41f4b71Sopenharmony_ci@Component 1015e41f4b71Sopenharmony_cistruct LocalSetSample { 1016e41f4b71Sopenharmony_ci @LocalStorageLink("set") memberSet: Set<number> = new Set([0, 1, 2, 3, 4]); 1017e41f4b71Sopenharmony_ci 1018e41f4b71Sopenharmony_ci build() { 1019e41f4b71Sopenharmony_ci Row() { 1020e41f4b71Sopenharmony_ci Column() { 1021e41f4b71Sopenharmony_ci ForEach(Array.from(this.memberSet.entries()), (item: [number, string]) => { 1022e41f4b71Sopenharmony_ci Text(`${item[0]}`) 1023e41f4b71Sopenharmony_ci .fontSize(30) 1024e41f4b71Sopenharmony_ci Divider() 1025e41f4b71Sopenharmony_ci }) 1026e41f4b71Sopenharmony_ci Button('init set') 1027e41f4b71Sopenharmony_ci .onClick(() => { 1028e41f4b71Sopenharmony_ci this.memberSet = new Set([0, 1, 2, 3, 4]); 1029e41f4b71Sopenharmony_ci }) 1030e41f4b71Sopenharmony_ci Button('set new one') 1031e41f4b71Sopenharmony_ci .onClick(() => { 1032e41f4b71Sopenharmony_ci this.memberSet.add(5); 1033e41f4b71Sopenharmony_ci }) 1034e41f4b71Sopenharmony_ci Button('clear') 1035e41f4b71Sopenharmony_ci .onClick(() => { 1036e41f4b71Sopenharmony_ci this.memberSet.clear(); 1037e41f4b71Sopenharmony_ci }) 1038e41f4b71Sopenharmony_ci Button('delete the first one') 1039e41f4b71Sopenharmony_ci .onClick(() => { 1040e41f4b71Sopenharmony_ci this.memberSet.delete(0); 1041e41f4b71Sopenharmony_ci }) 1042e41f4b71Sopenharmony_ci } 1043e41f4b71Sopenharmony_ci .width('100%') 1044e41f4b71Sopenharmony_ci } 1045e41f4b71Sopenharmony_ci .height('100%') 1046e41f4b71Sopenharmony_ci } 1047e41f4b71Sopenharmony_ci} 1048e41f4b71Sopenharmony_ci``` 1049e41f4b71Sopenharmony_ci 1050e41f4b71Sopenharmony_ci### 自定义组件外改变状态变量 1051e41f4b71Sopenharmony_ci 1052e41f4b71Sopenharmony_ci```ts 1053e41f4b71Sopenharmony_cilet storage = new LocalStorage(); 1054e41f4b71Sopenharmony_cistorage.setOrCreate('count', 47); 1055e41f4b71Sopenharmony_ci 1056e41f4b71Sopenharmony_ciclass Model { 1057e41f4b71Sopenharmony_ci storage: LocalStorage = storage; 1058e41f4b71Sopenharmony_ci 1059e41f4b71Sopenharmony_ci call(propName: string, value: number) { 1060e41f4b71Sopenharmony_ci this.storage.setOrCreate<number>(propName, value); 1061e41f4b71Sopenharmony_ci } 1062e41f4b71Sopenharmony_ci} 1063e41f4b71Sopenharmony_ci 1064e41f4b71Sopenharmony_cilet model: Model = new Model(); 1065e41f4b71Sopenharmony_ci 1066e41f4b71Sopenharmony_ci@Entry({ storage: storage }) 1067e41f4b71Sopenharmony_ci@Component 1068e41f4b71Sopenharmony_cistruct Test { 1069e41f4b71Sopenharmony_ci @LocalStorageLink('count') count: number = 0; 1070e41f4b71Sopenharmony_ci 1071e41f4b71Sopenharmony_ci build() { 1072e41f4b71Sopenharmony_ci Column() { 1073e41f4b71Sopenharmony_ci Text(`count值: ${this.count}`) 1074e41f4b71Sopenharmony_ci Button('change') 1075e41f4b71Sopenharmony_ci .onClick(() => { 1076e41f4b71Sopenharmony_ci model.call('count', this.count + 1); 1077e41f4b71Sopenharmony_ci }) 1078e41f4b71Sopenharmony_ci } 1079e41f4b71Sopenharmony_ci } 1080e41f4b71Sopenharmony_ci} 1081e41f4b71Sopenharmony_ci``` 1082e41f4b71Sopenharmony_ci 1083e41f4b71Sopenharmony_ci<!--no_check--> 1084