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![zh-cn_image_0000001501936014](figures/zh-cn_image_0000001501936014.png)
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![LocalStorageProp_framework_behavior](figures/LocalStorageProp_framework_behavior.png)
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![zh-cn_image_0000001552855957](figures/zh-cn_image_0000001552855957.png)
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![LocalStorageLink_framework_behavior](figures/LocalStorageLink_framework_behavior.png)
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&lt;number&gt;('countStorage')}”没有同步刷新,因为storage.get&lt;number&gt;('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