提交 6f249cc5 编写于 作者: Z zhuzijia

状态管理优秀实例

Signed-off-by: Nzhuzijia <zhuzijia@huawei.com>
Change-Id: Iab27489226c47b8ef78fedc6b965b437724c1337
上级 98988e7d
......@@ -74,8 +74,11 @@
- [其他状态管理概述](arkts-other-state-mgmt-functions-overview.md)
- [\@Watch装饰器:状态变量更改通知](arkts-watch.md)
- [$$语法:内置组件双向同步](arkts-two-way-sync.md)
- [MVVM模式](arkts-mvvm.md)
- [状态管理优秀实践](arkts-state-management-best-practices.md)
- 渲染控制
- [渲染控制概述](arkts-rendering-control-overview.md)
- [if/else:条件渲染](arkts-rendering-control-ifelse.md)
- [ForEach:循环渲染](arkts-rendering-control-foreach.md)
- [LazyForEach:数据懒加载](arkts-rendering-control-lazyforeach.md)
- [渲染控制优秀实践](arkts-rendering-control-best-practices.md)
# LocalStorage:页面级UI状态存储
LocalStorage是页面级的UI状态存储,通过\@Entry装饰器接的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility内,页面间共享状态。
LocalStorage是页面级的UI状态存储,通过\@Entry装饰器接的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility内,页面间共享状态。
本文仅介绍LocalStorage使用场景和相关的装饰器:\@LocalStorageProp和\@LocalStorageLink。
......
此差异已折叠。
# 渲染控制优秀实践
为了帮助应用程序开发人员提高其应用程序质量,本章节面向开发者提供了多个在开发ArkUI应用中常见场景和易错问题,并给出了对应的解决方案。此外,还提供了同一场景下,推荐用法和不推荐用法的对比和解释说明,更直观地展示两者区别,从而帮助开发者学习如果正确地在应用开发中使用渲染控制,进行高性能开发。
## 在ForEach数据源中添加元素
在ForEach数据源中添加元素导致数组项ID重复。
### 不推荐用法
下面示例使用ForEach方法迭代数组this.arr的每个元素,在Text组件进行显示,并在单击Text('Add arr element')时添加新的数组元素。
```ts
@Entry
@Component
struct Index {
@State arr: number[] = [1,2,3];
build() {
Column() {
ForEach(this.arr,
(item) => {
Text(`Item ${item}`)
},
item => item.toString())
Text('Add arr element')
.fontSize(20)
.onClick(()=>{
this.arr.push(4); // arr新增的元素,其在ForEach内的键值均为'4'
console.log("Arr elements: ", this.arr);
})
}
}
}
```
点击两次Text('Add arr element')时,数组this.arr每次都会添加新元素 4。但是在ForEach循环渲染中,第三个参数(item)=&gt; item.toString()需要生成Array每一个item对应的id值。该Array Id被要求是唯一的和稳定的。
- 唯一性:键值生成函数生成的每个数组项的id是不同的。
- 稳定性:当数组项ID发生变化时,ArkUI框架认为该数组项被替换或更改。
- ArkUI框架会对重复的ID告警,这种情况下框架的行为是未知的,特别是UI的更新在该场景下可能不起作用。
因此上述示例中,框架不会显示第二次及以后新添加的文本元素。因为这个元素不再是唯一的,他们都含有相同的id4。 但是如果删除ForEach第三个键值生成函数(item) =&gt; item.toString(),则触发onClick事件后每一个新添加的Text元素都会得到更新。这是因为框架使用了默认的Array id生成函数,即(item: any, index : number) =&gt; '${index}__${JSON.stringify(item)}'。它的兼容性更好但可能会导致不必要的UI更新,因此仍建议应用定义自己的键值生成函数。
## ForEach数据源更新
ForEach数据源更新时,数组项ID与原数组项ID重复不会重新创建该数组项。
### 不推荐用法
下面的示例定义了Index和Child两个组件。父组件Index有arr数组成员变量,初始值包含数字1、2、3。Child定义\@Prop value,接收父组件中arr数组中的一个元素。
```ts
@Component
struct Child {
@Prop value: number;
build() {
Text(`${this.value}`)
.fontSize(50)
.onClick(() => {
this.value++ // 点击改变@Prop的值
})
}
}
@Entry
@Component
struct Index {
@State arr: number[] = [1, 2, 3];
build() {
Row() {
Column() {
// 对照组
Child({ value: this.arr[0] })
Child({ value: this.arr[1] })
Child({ value: this.arr[2] })
Divider().height(5)
ForEach(this.arr,
item => {
Child({ value: item })
},
item => item.toString() // 键值,标识id
)
Text('Parent: replace entire arr')
.fontSize(50)
.onClick(() => {
// 两个数组项内均含有'3',ForEach内的id没有发生变化
// 意味着ForEach不会更新该Child实例,@Prop也不会在父组件处被更新
this.arr = (this.arr[0] == 1) ? [3, 4, 5] : [1, 2, 3];
})
}
}
}
}
```
当触发文本组件Parent: replace entire arr的onClick事件时,状态变量数组arr根据自身第一个元素的值将被[3, 4, 5]或[1, 2, 3]替换,但是ForEach里初始被创建的\@Prop传入值为3的Child组件并不会更新。
因为,老数组和新数组初始均含有同一个值的元素(数字3),而且该元素生成的标识id在父组件里没有变化。因此ForEach没有识别出对应的Child实例需要被新的输入值更新,对应的子组件内\@Prop也没有更新。
![zh-cn_image_0000001604900446](figures/zh-cn_image_0000001604900446.png)
可以在arr中用一个唯一的元素代替重复的元素3来观察本事件的行为表现。当恰当的替换掉数组时,接下来应用的表现才是符合预期的。
\ No newline at end of file
......@@ -21,6 +21,9 @@
## AppStorage
AppStorage具体UI使用说明,详见[AppStorage(应用全局的UI状态存储)](../../quick-start/arkts-appstorage.md)
### link<sup>10+</sup>
static link<T>(propName: string): SubscribedAbstractProperty<T>
......@@ -698,6 +701,9 @@ let res: number = AppStorage.Size(); // 1
## LocalStorage<sup>9+</sup>
LocalStorage具体UI使用说明,详见[LocalStorage(页面级UI状态存储)](../../quick-start/arkts-localstorage.md)
### constructor<sup>9+</sup>
constructor(initializingProperties?: Object)
......@@ -735,9 +741,7 @@ static getShared(): LocalStorage
| [LocalStorage](#localstorage9) | 返回LocalStorage实例。 |
```ts
let storage: LocalStorage = LocalStorage.getShared();
```
getShared具体使用,见[在UI页面通过getShared接口获取在通过loadContent共享的LocalStorage实例](../../quick-start/arkts-localstorage.md#将localstorage实例从uiability共享到一个或多个视图)
### has<sup>9+</sup>
......@@ -1161,6 +1165,10 @@ link.set(50); // PropB -> 49, link.get() --> undefined
## PersistentStorage
PersistentStorage具体UI使用说明,详见[PersistentStorage(持久化存储UI状态)](../../quick-start/arkts-persiststorage.md)
### PersistPropsOptions
| 参数名 | 类型 | 必填 | 参数描述 |
......@@ -1196,9 +1204,7 @@ static persistProp&lt;T&gt;(key: string, defaultValue: T): void
**示例:**
```ts
PersistentStorage.persistProp('highScore', '0');
```
persistProp具体使用,见[从AppStorage中访问PersistentStorage初始化的属性](../../quick-start/arkts-persiststorage.md#从appstorage中访问persistentstorage初始化的属性)
### deleteProp<sup>10+</sup>
......@@ -1352,6 +1358,9 @@ let keys: Array<string> = PersistentStorage.Keys();
## Environment
Environment具体使用说明,详见[Environment(设备环境查询)](../../quick-start/arkts-environment.md)
### EnvPropsOptions
| 参数名 | 类型 | 必填 | 参数描述 |
......@@ -1386,21 +1395,7 @@ static envProp&lt;S&gt;(key: string, value: S): boolean
**示例:**
```ts
Environment.envProp('accessibilityEnabled', 'default');
```
### 内置环境变量说明
| key | 类型 | 说明 |
| -------------------- | --------------- | ---------------------------------------- |
| accessibilityEnabled | string | 无障碍屏幕朗读是否启用。 |
| colorMode | ColorMode | 深浅色模式,可选值为:<br/>-&nbsp;ColorMode.LIGHT:浅色模式;<br/>-&nbsp;ColorMode.DARK:深色模式。 |
| fontScale | number | 字体大小比例。 |
| fontWeightScale | number | 字重比例。 |
| layoutDirection | LayoutDirection | 布局方向类型,可选值为:<br/>-&nbsp;LayoutDirection.LTR:从左到右;<br/>-&nbsp;LayoutDirection.RTL:从右到左。 |
| languageCode | string | 当前系统语言,小写字母,例如zh。 |
envProp具体使用,见[从UI中访问Environment参数](../../quick-start/arkts-environment.md#从ui中访问environment参数)
### envProps<sup>10+</sup>
......@@ -1525,4 +1520,16 @@ Environment.EnvProps([{ key: 'accessibilityEnabled', defaultValue: 'default' },
}, { key: 'prop', defaultValue: 'hhhh' }]);
let keys: Array<string> = Environment.Keys(); // accessibilityEnabled, languageCode, prop
```
\ No newline at end of file
```
## 内置环境变量说明
| key | 类型 | 说明 |
| -------------------- | --------------- | ---------------------------------------- |
| accessibilityEnabled | string | 无障碍屏幕朗读是否启用。 |
| colorMode | ColorMode | 深浅色模式,可选值为:<br/>-&nbsp;ColorMode.LIGHT:浅色模式;<br/>-&nbsp;ColorMode.DARK:深色模式。 |
| fontScale | number | 字体大小比例。 |
| fontWeightScale | number | 字重比例。 |
| layoutDirection | LayoutDirection | 布局方向类型,可选值为:<br/>-&nbsp;LayoutDirection.LTR:从左到右;<br/>-&nbsp;LayoutDirection.RTL:从右到左。 |
| languageCode | string | 当前系统语言,小写字母,例如zh。 |
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册