android2harmony 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/scripts/hmos-precheck/index.mjs +0 -8
- package/agents/self-tester.md +339 -0
- package/dist/index.js +635 -77
- package/dist/index.js.map +4 -4
- package/package.json +37 -29
- package/skills/hmos-incremental-ui-align/README.md +251 -0
- package/skills/hmos-incremental-ui-align/SKILL.md +365 -0
- package/skills/hmos-incremental-ui-align/diff_analysis.md +53 -0
- package/skills/hmos-incremental-ui-align/page_align.md +62 -0
- package/skills/hmos-incremental-ui-align/references/Comparison_Template.md +38 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2089 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +903 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/MVVM/346/250/241/345/274/217V1.md +911 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +355 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/!!/350/257/255/346/263/225/357/274/232/345/217/214/345/220/221/347/273/221/345/256/232.md +206 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@Computed/350/243/205/351/245/260/345/231/250/357/274/232/350/256/241/347/256/227/345/261/236/346/200/247.md +373 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@Event/350/243/205/351/245/260/345/231/250/357/274/232/350/247/204/350/214/203/347/273/204/344/273/266/350/276/223/345/207/272.md +158 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@Local/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/351/203/250/347/212/266/346/200/201.md +750 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@Monitor/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/344/277/256/346/224/271/345/274/202/346/255/245/347/233/221/345/220/254.md +1704 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@ObservedV2/350/243/205/351/245/260/345/231/250/345/222/214@Trace/350/243/205/351/245/260/345/231/250/357/274/232/347/261/273/345/261/236/346/200/247/345/217/230/345/214/226/350/247/202/346/265/213.md +1012 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@Once/350/243/205/351/245/260/345/231/250/357/274/232/345/210/235/345/247/213/345/214/226/345/220/214/346/255/245/344/270/200/346/254/241.md +164 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@Param/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/244/226/351/203/250/350/276/223/345/205/245.md +840 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@Provider/350/243/205/351/245/260/345/231/250/345/222/214@Consumer/350/243/205/351/245/260/345/231/250/357/274/232/350/267/250/347/273/204/344/273/266/345/261/202/347/272/247/345/217/214/345/220/221/345/220/214/346/255/245.md +856 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@Type/350/243/205/351/245/260/345/231/250/357/274/232/346/240/207/350/256/260/347/261/273/345/261/236/346/200/247/347/232/204/347/261/273/345/236/213.md +83 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/AppStorageV2/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200UI/347/212/266/346/200/201/345/255/230/345/202/250.md +294 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/MVVM/346/250/241/345/274/217/357/274/210V2/357/274/211.md +1407 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/PersistenceV2/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +1220 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/_/350/214/203/345/274/217/351/200/211/346/213/251/350/257/264/346/230/216.md +47 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2//347/212/266/346/200/201/347/256/241/347/220/206V1/345/220/221V2/350/277/201/347/247/273/344/270/216/346/267/267/347/224/250/346/214/207/345/257/274.md +840 -0
- package/skills/hmos-incremental-ui-align/references/State_Model_Template.md +74 -0
- package/skills/hmos-incremental-ui-align/references/UI_Analysis_Template.md +34 -0
- package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +2533 -0
- package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-interaction-mapping-reference.md +555 -0
- package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-layout-mapping-reference.md +117 -0
- package/skills/hmos-incremental-ui-align/scripts/app_feature_verify.ts +999 -0
- package/skills/hmos-incremental-ui-align/scripts/extract_checklist.ts +343 -0
- package/skills/hmos-incremental-ui-align/scripts/navigation-capure.md +76 -0
- package/skills/hmos-incremental-ui-align/scripts/page_capture.ts +977 -0
- package/skills/hmos-incremental-ui-align/scripts/page_capture_burst.ts +188 -0
- package/skills/hmos-spec-generate/SKILL.md +1 -1
- package/tools/autotest/deps/autotest-agent-0.1.1.tgz +0 -0
- package/tools/autotest/engine/batch-launcher.ts +326 -0
- package/tools/autotest/engine/report-tool.ts +773 -0
- package/tools/autotest/engine/self-test-runner.ts +1024 -0
- package/tools/autotest/engine/testcases-tool.ts +246 -0
- package/tools/autotest/resolve-metadata-tool.ts +143 -0
- package/tools/autotest/runner/logger.ts +45 -0
- package/tools/autotest/runner/process-utils.ts +41 -0
- package/tools/autotest/validate.ts +115 -0
|
@@ -0,0 +1,840 @@
|
|
|
1
|
+
## 概述
|
|
2
|
+
|
|
3
|
+
在状态管理框架的迭代演进中,先后推出了[状态管理V1](../../状态管理(V1)/arkts-state-management-v1.md)(简称V1)和[状态管理V2](../../状态管理(V2)/arkts-state-management-v2.md)(简称V2)。V1侧重于组件层级的状态管理,例如,需要开发者通过[@ObjectLink](../../状态管理(V1)/管理组件拥有的状态/@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化/arkts-observed-and-objectlink.md)逐层拆解嵌套类以使深层次数据具备观测能力。V2则实现了能力升级,增强了对数据对象的深度观察与管理能力,例如,V2的[@Monitor](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-monitor)不仅能够感知变化后的数据,还能获取变化前的数据。通过V2版本,开发者可以更灵活地操控数据与状态,实现更高效的UI刷新,提升开发体验与应用性能。
|
|
4
|
+
|
|
5
|
+
为帮助已基于V1开发的应用平滑迁移至V2,本文提供了[状态管理V1向V2的迁移指导](../状态管理V1向V2迁移场景/arkts-state-management-v1-v2-migration-guide.md),涵盖迁移过程中的常见场景,便于开发者结合自身业务灵活适配。同时,针对迁移过渡阶段可能出现的[状态管理V1和V2混用场景](../状态管理V1和V2混用场景/v1v2-mixing.md),文章讲解了V1使用V2组件的规则和实操方法,并根据API version 19前后的差异,分别提供了针对性解决方案,帮助开发者实现逐步改造。
|
|
6
|
+
|
|
7
|
+
## V1V2使用指引
|
|
8
|
+
|
|
9
|
+
针对V1与V2的使用,建议依据应用需求选择。鉴于V2为V1的增强版本,且正持续迭代优化,功能上更推荐新开发时使用。主要参考策略如下:
|
|
10
|
+
|
|
11
|
+
1. 对于新开发的应用,建议直接采用V2版本进行开发。
|
|
12
|
+
2. 对于已使用V1的应用,如果V1的功能和性能满足需求,无需立即切换至V2。
|
|
13
|
+
3. 对于需要在现阶段混用V1和V2的场景,请参阅[状态管理V1和V2混用场景](../状态管理V1和V2混用场景/v1v2-mixing.md)文档。编译器、工具链、DevEco Studio会对某些误用和混用场景进行校验,建议开发者遵循该文档,避免因双重代理(数据被V1和V2同时代理监听)等问题给应用带来不确定性。
|
|
14
|
+
|
|
15
|
+
## V1与V2差异对比
|
|
16
|
+
|
|
17
|
+
关于V1与V2部分的差异,具体V1和V2的区别可以参见[状态管理概述](../../状态管理概述/arkts-state-management-overview.md)以及[状态管理V1和V2更新机制差异](../../状态管理V1和V2更新机制差异/arkts-v1-v2-update-difference.md)。这部分内容,可以帮助开发者理解V1与V2运行背后的差异点,在适配时,起到事半功倍的效果。
|
|
18
|
+
|
|
19
|
+
## V1与V2能力对照迁移表
|
|
20
|
+
|
|
21
|
+
| V1装饰器名称\场景 | V2装饰器名称\API | 说明 |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| [@Component](../../../学习UI范式基本语法/自定义组件/创建自定义组件/arkts-create-custom-components.md#component) | [@ComponentV2](../../../学习UI范式基本语法/自定义组件/创建自定义组件/arkts-create-custom-components.md#componentv2) | @Component为搭配V1状态变量使用的自定义组件装饰器。 @ComponentV2为搭配V2状态变量使用的自定义组件装饰器。 |
|
|
24
|
+
| [@State](../../状态管理(V1)/管理组件拥有的状态/@State装饰器:组件内状态/arkts-state.md) | 无外部初始化:[@Local](../../状态管理(V2)/管理组件拥有的状态/@Local装饰器:组件内部状态/arkts-new-local.md) 外部初始化一次:[@Param](../../状态管理(V2)/管理组件拥有的状态/@Param:组件外部输入/arkts-new-param.md)、[@Once](../../状态管理(V2)/管理组件拥有的状态/@Once:初始化同步一次/arkts-new-once.md) | @State和@Local类似都是数据源的概念,在不需要外部传入初始化时,可直接迁移。如果需要外部传入初始化,则可以迁移为@Param @Once。详情见迁移场景--[@State->@Local](../状态管理V1向V2迁移场景/组件内状态变量迁移/arkts-v1-v2-migration-inner-component.md#state---local)。如果使用滚动组件关联的[WaterFlowSections](../../../../../../../harmonyos-references/ArkUI(方舟UI框架)/ArkTS组件/滚动与滑动/WaterFlow/ts-container-waterflow.md#waterflowsections12)/[ChildrenMainSize](../../../../../../../harmonyos-references/ArkUI(方舟UI框架)/ArkTS组件/滚动与滑动/滚动组件通用接口/ts-container-scrollable-common.md#childrenmainsize12对象说明),需要使用[makeObserved](../../辅助接口/makeObserved接口:将非观察数据变为可观察数据/arkts-new-makeobserved.md),详情见迁移场景--[滚动组件](../状态管理V1向V2迁移场景/内置对象的迁移/arkts-v1-v2-migration-inner-object.md#滚动组件)。 |
|
|
25
|
+
| [@Prop](../../状态管理(V1)/管理组件拥有的状态/@Prop装饰器:父子单向同步/arkts-prop.md) | [@Param](../../状态管理(V2)/管理组件拥有的状态/@Param:组件外部输入/arkts-new-param.md) | @Prop和@Param类似都是自定义组件参数的概念。当输入参数为复杂类型时,@Prop为深拷贝,@Param为引用。详情见迁移场景--[@Prop -> @Param](../状态管理V1向V2迁移场景/组件内状态变量迁移/arkts-v1-v2-migration-inner-component.md#prop---param)。 |
|
|
26
|
+
| [@Link](../../状态管理(V1)/管理组件拥有的状态/@Link装饰器:父子双向同步/arkts-link.md) | [@Param](../../状态管理(V2)/管理组件拥有的状态/@Param:组件外部输入/arkts-new-param.md)、[@Event](../../状态管理(V2)/管理组件拥有的状态/@Event装饰器:规范组件输出/arkts-new-event.md) | @Link是框架自己封装实现的双向同步,对于V2开发者可以通过@Param@Event自己实现双向同步。详情见迁移场景--[@Link -> @Param/@Event](../状态管理V1向V2迁移场景/组件内状态变量迁移/arkts-v1-v2-migration-inner-component.md#link---paramevent)。 |
|
|
27
|
+
| [@Observed](../../状态管理(V1)/管理组件拥有的状态/@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化/arkts-observed-and-objectlink.md) | [@ObservedV2](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace) | 表明当前对象为可观察对象。但两者能力并不相同。 @Observed可观察第一层的属性,需要搭配[@ObjectLink](../../状态管理(V1)/管理组件拥有的状态/@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化/arkts-observed-and-objectlink.md)使用才能生效。 @ObservedV2本身无观察能力,仅代表当前class可被观察,如果要观察其属性,需要搭配@Trace使用。详情见迁移场景---[@ObjectLink/@Observed/@Track -> @ObservedV2/@Trace](../状态管理V1向V2迁移场景/数据对象状态变量迁移/arkts-v1-v2-migration-inner-class.md#objectlinkobservedtrack---observedv2trace)。 |
|
|
28
|
+
| [@ObjectLink](../../状态管理(V1)/管理组件拥有的状态/@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化/arkts-observed-and-objectlink.md) | [@ObservedV2](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace)、[@Trace](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace) | 直接兼容,@ObjectLink需要被@Observed装饰的class的实例初始化,主要应用于观察嵌套类场景。在状态管理V2中可以使用@ObservedV2@Trace。详情见迁移场景---[@ObjectLink/@Observed/@Track -> @ObservedV2/@Trace](../状态管理V1向V2迁移场景/数据对象状态变量迁移/arkts-v1-v2-migration-inner-class.md#objectlinkobservedtrack---observedv2trace)。 |
|
|
29
|
+
| [@Track](../../状态管理(V1)/管理数据对象的状态/@Track装饰器:class对象属性级更新/arkts-track.md) | [@Trace](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace) | V1装饰器@Track为精确观察,不使用则无法做到类属性的精准观察。 V2@Trace装饰的属性可以被精确跟踪观察。详情见迁移场景---[@ObjectLink/@Observed/@Track -> @ObservedV2/@Trace](../状态管理V1向V2迁移场景/数据对象状态变量迁移/arkts-v1-v2-migration-inner-class.md#objectlinkobservedtrack---observedv2trace)。 |
|
|
30
|
+
| [@Provide](../../状态管理(V1)/管理组件拥有的状态/@Provide装饰器和@Consume装饰器:与后代组件双向同步/arkts-provide-and-consume.md)、[@Consume](../../状态管理(V1)/管理组件拥有的状态/@Provide装饰器和@Consume装饰器:与后代组件双向同步/arkts-provide-and-consume.md) | [@Provider](../../状态管理(V2)/管理组件拥有的状态/@Provider装饰器和@Consumer装饰器:跨组件层级双向同步/arkts-new-provider-and-consumer.md)、[@Consumer](../../状态管理(V2)/管理组件拥有的状态/@Provider装饰器和@Consumer装饰器:跨组件层级双向同步/arkts-new-provider-and-consumer.md) | 兼容。详情见[@Provide/@Consume迁移场景](../状态管理V1向V2迁移场景/组件内状态变量迁移/arkts-v1-v2-migration-inner-component.md#provideconsume---providerconsumer)。 |
|
|
31
|
+
| [@Watch](../../状态管理(V1)/管理组件拥有的状态/@Watch装饰器:状态变量更改通知/arkts-watch.md) | [@Monitor](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-monitor) | @Watch用于监听V1状态变量的变化,具有监听状态变量本身和其第一层属性变化的能力。状态变量可观察到的变化会触发其@Watch监听事件,详情见迁移场景--[@Watch -> @Monitor](../状态管理V1向V2迁移场景/组件内状态变量迁移/arkts-v1-v2-migration-inner-component.md#watch---monitor)。 @Monitor用于监听V2状态变量的变化,搭配@Observed和@Trace一起使用,可有深层监听的能力。状态变量在一次事件中多次变化时,仅会以最终的结果判断是否触发@Monitor监听事件。 |
|
|
32
|
+
| 无计算属性能力 | [@Computed](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-computed) | 状态管理V1无计算属性相关能力,状态管理V2可使用@Computed避免重复计算。详情见迁移场景--[重复计算->@Computed计算属性](../状态管理V1向V2迁移场景/组件内状态变量迁移/arkts-v1-v2-migration-inner-component.md#重复计算---computed计算属性)。 |
|
|
33
|
+
| [LocalStorage](../../状态管理(V1)/管理应用拥有的状态/LocalStorage:页面级UI状态存储/arkts-localstorage.md) | [@ObservedV2](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace)、[@Trace](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace) | 兼容。详情见迁移场景--[LocalStorage->@ObservedV2/@Trace](../状态管理V1向V2迁移场景/应用内状态变量迁移/arkts-v1-v2-migration-application.md#localstorage-observedv2trace)。 |
|
|
34
|
+
| [AppStorage](../../状态管理(V1)/管理应用拥有的状态/AppStorage:应用全局的UI状态存储/arkts-appstorage.md) | [AppStorageV2](<../../状态管理(V2)/管理应用拥有的状态/AppStorageV2 应用全局UI状态存储/arkts-new-appstoragev2.md>) | 兼容。详情见迁移场景--[AppStorage->AppStorageV2](../状态管理V1向V2迁移场景/应用内状态变量迁移/arkts-v1-v2-migration-application.md#appstorage-appstoragev2)。 |
|
|
35
|
+
| [Environment](../../状态管理(V1)/管理应用拥有的状态/Environment:设备环境查询/arkts-environment.md) | 调用Ability接口获取系统环境变量 | Environment获取环境变量能力和AppStorage耦合。在V2中可直接调用Ability接口获取系统环境变量。详情见迁移场景--[Environment->调用Ability接口直接获取系统环境变量](../状态管理V1向V2迁移场景/应用内状态变量迁移/arkts-v1-v2-migration-application.md#environment-调用ability接口直接获取系统环境变量)。 |
|
|
36
|
+
| [PersistentStorage](../../状态管理(V1)/管理应用拥有的状态/PersistentStorage:持久化存储UI状态/arkts-persiststorage.md) | [PersistenceV2](<../../状态管理(V2)/管理应用拥有的状态/PersistenceV2 持久化存储UI状态/arkts-new-persistencev2.md>) | PersistentStorage持久化能力和AppStorage耦合,PersistenceV2持久化能力可独立使用。详情见迁移场景--[PersistentStorage->PersistenceV2](../状态管理V1向V2迁移场景/应用内状态变量迁移/arkts-v1-v2-migration-application.md#persistentstorage-persistencev2)。 |
|
|
37
|
+
|
|
38
|
+
## 状态管理V1向V2逐步迁移策略
|
|
39
|
+
|
|
40
|
+
对于已经使用V1开发的大型应用,通常难以一次性从V1迁移到V2,而是需要分批次、分组件地逐步迁移;首先考虑将V1组件迁移为V2组件,这部分可以参考[状态管理V1向V2迁移场景](../状态管理V1向V2迁移场景/arkts-state-management-v1-v2-migration-guide.md)进行适配。
|
|
41
|
+
|
|
42
|
+
迁移过程中由于V1与V2存在共存的情况,这就必然会带来V1和V2的混用。针对混用的场景,可以参考[状态管理V1和V2混用场景](../状态管理V1和V2混用场景/v1v2-mixing.md)进行适配,并最终完成V1->V2的全量适配。
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 概述
|
|
47
|
+
|
|
48
|
+
为了帮助开发者顺利地向状态管理V2迁移,从API version 19开始,减少了对状态管理V1和V2混用场景的约束。具体变更可参考[限制条件](arkts-v1-v2-mixusage.md#限制条件)。同时提供新的方法[enableV2Compatibility](<../../../../../../../../harmonyos-references/ArkUI(方舟UI框架)/ArkTS API/UI界面/@ohos.arkui.StateManagement (状态管理)/js-apis-statemanagement.md#enablev2compatibility19>)和[makeV1Observed](<../../../../../../../../harmonyos-references/ArkUI(方舟UI框架)/ArkTS API/UI界面/@ohos.arkui.StateManagement (状态管理)/js-apis-statemanagement.md#makev1observed19>)来帮助开发者解决在迁移过程中遇到的混用问题。
|
|
49
|
+
|
|
50
|
+
说明
|
|
51
|
+
|
|
52
|
+
本文档中使用“->”表示变量的传递,比如“V1->V2”,表示V1状态变量向V2状态变量传递。
|
|
53
|
+
|
|
54
|
+
## 限制条件
|
|
55
|
+
|
|
56
|
+
1. V1装饰器不能和[@ObservedV2](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace)一起使用。因为@ObservedV2/@Trace有自己独立的观察能力,不仅可以在[@ComponentV2](../../../../学习UI范式基本语法/自定义组件/创建自定义组件/arkts-create-custom-components.md#componentv2)中使用,也可以独立在[@Component](../../../../学习UI范式基本语法/自定义组件/创建自定义组件/arkts-create-custom-components.md#component)中使用,状态管理框架不希望其观察能力和V1的观察能力混合使用,所以依旧维持禁止现状。
|
|
57
|
+
2. V2->V1,V1不支持用装饰器接收@ObservedV2装饰的class,否则编译报错。
|
|
58
|
+
3. V1中[@Link](../../../状态管理(V1)/管理组件拥有的状态/@Link装饰器:父子双向同步/arkts-link.md)遵循其原本初始化规则,只能被V1状态变量初始化,详情见[@Link初始化规则示意图](../../../状态管理(V1)/管理组件拥有的状态/@Link装饰器:父子双向同步/arkts-link.md#变量的传递访问规则说明)。因为V1中[@Link](../../../状态管理(V1)/管理组件拥有的状态/@Link装饰器:父子双向同步/arkts-link.md)仅能和V1状态变量建立双向同步关系,而V2中如果想实现双向同步,可以使用@Param、@Event,具体例子见[@Link -> @Param/@Event迁移场景](../../状态管理V1向V2迁移场景/组件内状态变量迁移/arkts-v1-v2-migration-inner-component.md#link---paramevent)。
|
|
59
|
+
|
|
60
|
+
## 新增接口
|
|
61
|
+
|
|
62
|
+
### makeV1Observed
|
|
63
|
+
|
|
64
|
+
[makeV1Observed](<../../../../../../../../harmonyos-references/ArkUI(方舟UI框架)/ArkTS API/UI界面/@ohos.arkui.StateManagement (状态管理)/js-apis-statemanagement.md#makev1observed19>)将不可观察的对象包装成状态管理V1可观察的对象,能力等同于@Observed,其返回值可初始化@ObjectLink。
|
|
65
|
+
|
|
66
|
+
说明
|
|
67
|
+
|
|
68
|
+
从API version 19开始,开发者可以使用UIUtils中的makeV1Observed接口将不可观察的对象包装成状态管理V1可观察的对象。
|
|
69
|
+
|
|
70
|
+
**接口说明**
|
|
71
|
+
|
|
72
|
+
* makeV1Observed主要和enableV2Compatibility搭配使用,实现V2->V1的传递。
|
|
73
|
+
* makeV1Observed可将普通class、Array、Map、Set、Date类型转换为V1的状态变量,其能力等同于@Observed,所以其返回值可以初始化@ObjectLink。
|
|
74
|
+
* 如果makeV1Observed接受的数据已经是V1的状态变量,则返回自身,不做任何改变。
|
|
75
|
+
* makeV1Observed不会递归执行,仅会将第一层包装成V1的状态变量。
|
|
76
|
+
|
|
77
|
+
**限制条件**
|
|
78
|
+
|
|
79
|
+
* 不支持[collections类型](<../../../../../../../../harmonyos-references/ArkTS(方舟编程语言)/ArkTS API/@arkts.collections (ArkTS容器集)/模块描述/arkts-apis-arkts-collections.md>)和[@Sendable](../../../../../../ArkTS(方舟编程语言)/ArkTS并发/并发线程间通信/线程间通信对象/Sendable对象/Sendable对象简介/arkts-sendable.md)装饰的class。
|
|
80
|
+
* 不支持非object类型。
|
|
81
|
+
* 不支持undefined、null。
|
|
82
|
+
* 不支持@ObservedV2、[makeObserved](<../../../../../../../../harmonyos-references/ArkUI(方舟UI框架)/ArkTS API/UI界面/@ohos.arkui.StateManagement (状态管理)/js-apis-statemanagement.md#makeobserved>)的返回值和V2装饰器装饰的built-in类型的变量(Array、Map、Set和Date)。
|
|
83
|
+
|
|
84
|
+
### enableV2Compatibility
|
|
85
|
+
|
|
86
|
+
[enableV2Compatibility](<../../../../../../../../harmonyos-references/ArkUI(方舟UI框架)/ArkTS API/UI界面/@ohos.arkui.StateManagement (状态管理)/js-apis-statemanagement.md#enablev2compatibility19>)将V1的状态变量使能V2的观察能力,即让V1状态变量可以在@ComponentV2中观察到变化。
|
|
87
|
+
|
|
88
|
+
说明
|
|
89
|
+
|
|
90
|
+
从API version 19开始,开发者可以使用UIUtils中的enableV2Compatibility接口将V1的状态变量兼容V2中使用。
|
|
91
|
+
|
|
92
|
+
**接口说明**
|
|
93
|
+
|
|
94
|
+
* 该接口主要应用于V1->V2的场景,V1的状态变量调用该接口后,传递到@ComponentV2中,则可以在V2中观察到变化,从而实现数据的联动刷新。
|
|
95
|
+
* enableV2Compatibility只能作用于V1的状态变量。V1状态变量为V1装饰器装饰的变量,即@Observed装饰的变量,或[@State](../../../状态管理(V1)/管理组件拥有的状态/@State装饰器:组件内状态/arkts-state.md)、[@Prop](../../../状态管理(V1)/管理组件拥有的状态/@Prop装饰器:父子单向同步/arkts-prop.md)、[@Link](../../../状态管理(V1)/管理组件拥有的状态/@Link装饰器:父子双向同步/arkts-link.md)、[@Provide](../../../状态管理(V1)/管理组件拥有的状态/@Provide装饰器和@Consume装饰器:与后代组件双向同步/arkts-provide-and-consume.md)、[@Consume](../../../状态管理(V1)/管理组件拥有的状态/@Provide装饰器和@Consume装饰器:与后代组件双向同步/arkts-provide-and-consume.md)和[@ObjectLink](../../../状态管理(V1)/管理组件拥有的状态/@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化/arkts-observed-and-objectlink.md)(@ObjectLink需是@Observed装饰的实例或者makeV1Observed的返回值)装饰的变量。否则,将返回入参自身。
|
|
96
|
+
* enableV2Compatibility会递归遍历class的所有属性,Array/Set/Map的所有子项,直到遇到非V1状态变量的数据,则停止当前分支的遍历。
|
|
97
|
+
|
|
98
|
+
**限制条件**
|
|
99
|
+
|
|
100
|
+
* 不支持非object类型。
|
|
101
|
+
* 不支持undefined、null。
|
|
102
|
+
* 不支持非V1的状态变量数据。
|
|
103
|
+
* 不支持@ObservedV2、[makeObserved](<../../../../../../../../harmonyos-references/ArkUI(方舟UI框架)/ArkTS API/UI界面/@ohos.arkui.StateManagement (状态管理)/js-apis-statemanagement.md#makeobserved>)的返回值和V2装饰器装饰的built-in类型的变量(Array、Map、Set和Date)。
|
|
104
|
+
|
|
105
|
+
## 混用规则
|
|
106
|
+
|
|
107
|
+
* V1->V2传递复杂类型数据,需要调用enableV2Compatibility,否则无法实现V1和V2的数据联动,建议在V2组件的构造处调用,否则当变量被整体赋值时,需要再次手动调用enableV2Compatibility。
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
1. // 建议用法,this.state = new ObservedClass()时无需再调用UIUtils.enableV2Compatibility,减少代码量
|
|
111
|
+
2. SubComponentV2({param: UIUtils.enableV2Compatibility(this.state)})
|
|
112
|
+
|
|
113
|
+
4. // 不建议用法,state做整体赋值时,需要再次调用UIUtils.enableV2Compatibility
|
|
114
|
+
5. // 否则传递给SubComponentV2的V1变量是无法在V2中观察的
|
|
115
|
+
6. // @State state: ObservedClass = UIUtils.enableV2Compatibility(new ObservedClass());
|
|
116
|
+
7. // this.state = UIUtils.enableV2Compatibility(new ObservedClass());
|
|
117
|
+
8. SubComponentV2({param: this.state})
|
|
118
|
+
```
|
|
119
|
+
* V2->V1传递复杂类型数据,在V2中优先声明成V1的状态变量数据,并调用UIUtils.enableV2Compatibility。因为在状态管理V1中,状态变量默认有观察第一层的能力,而状态管理V2仅有观察自身的能力,如果希望双方数据联动,则需要调用UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())拉齐双方的观察能力。
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
1. // 建议用法
|
|
123
|
+
2. @Local unObservedClass: UnObservedClass = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed(new UnObservedClass()));
|
|
124
|
+
|
|
125
|
+
4. // 建议用法,ObservedClass是@Observed装饰的class
|
|
126
|
+
5. @Local observedClass: ObservedClass = UIUtils.enableV2Compatibility(new ObservedClass());
|
|
127
|
+
```
|
|
128
|
+
* UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())不会改变V1和V2本身观察能力。
|
|
129
|
+
|
|
130
|
+
+ 在V1中,UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())等于V1的观察能力,观察数据本身的赋值和第一层属性的赋值,无法深度观察,如果需要深度观察,则需要配合@ObjectLink。
|
|
131
|
+
+ 在V2中,UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())可以深度观察,但是需要每一层都是@Observed装饰的class,或者是makeV1Observed的返回值。
|
|
132
|
+
+ 不使用enableV2Compatibility和makeV1Observed会导致双重代理问题,使同一状态对象被V1和V2两套状态管理体系同时生成代理对象,从而引起监听逻辑冲突。
|
|
133
|
+
* 当数据已使用V2观察能力,即调用UIUtils.enableV2Compatibility后,会将新的数据默认使用V2观察能力,但需要开发者确保新增数据是@Observed装饰的class,或者是makeV1Observed的返回值。完整例子可见[传递嵌套类型(V1->V2)](arkts-v1-v2-mixusage.md#传递嵌套类型v1-v2)、[传递嵌套类型(V2->V1)](arkts-v1-v2-mixusage.md#传递嵌套类型v2-v1)。
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
1. let arr: Array<ArrayItem> = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed(new ArrayItem()));
|
|
137
|
+
|
|
138
|
+
3. arr.push(new ArrayItem()); // 新增数据不是V1状态变量,所以不会具有V2观察能力
|
|
139
|
+
4. arr.push(UIUtils.makeV1Observed(new ArrayItem())); // 新增数据是V1的状态变量,默认在V2中可观察
|
|
140
|
+
```
|
|
141
|
+
* 对于built-in类型,如Array、Map、Set和Date,V1和V2都可以观察自身赋值和其API的调用所带来的变化。虽然开发者在不调用UIUtils.enableV2Compatibility时,也可以在一些简单场景下实现数据刷新,但是会带来双重代理导致性能较差的问题,所以建议开发者使用UIUtils.enableV2Compatibility(UIUtils.makeV1Observed()),具体例子见[传递内置类型(V1->V2)](arkts-v1-v2-mixusage.md#传递内置类型v1-v2)、[传递内置类型(V2->V1)](arkts-v1-v2-mixusage.md#传递内置类型v2-v1)。
|
|
142
|
+
* 对于有[@Track](../../../状态管理(V1)/管理数据对象的状态/@Track装饰器:class对象属性级更新/arkts-track.md)装饰属性的类,非@Track装饰的属性在@ComponentV2中使用不会崩溃,在@Component中使用仍会崩溃。具体例子见[传递class类型(V1->V2)](arkts-v1-v2-mixusage.md#传递class类型v1-v2)、[传递class类型(V2->V1)](arkts-v1-v2-mixusage.md#传递class类型v2-v1)。
|
|
143
|
+
|
|
144
|
+
开发者在使用这两个接口混用V1V2时,可遵循下图逻辑。
|
|
145
|
+
|
|
146
|
+

|
|
147
|
+
|
|
148
|
+
## V1中使用V2的自定义组件
|
|
149
|
+
|
|
150
|
+
### 传递class类型(V1->V2)
|
|
151
|
+
|
|
152
|
+
**普通class**
|
|
153
|
+
|
|
154
|
+
以下代码中,V1的状态变量在传递给V2时,调用enableV2Compatibility接口,使V1的变量observedClass在V2组件中有观察能力。
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
158
|
+
|
|
159
|
+
3. class ObservedClass {
|
|
160
|
+
4. public name: string = 'Tom';
|
|
161
|
+
5. }
|
|
162
|
+
|
|
163
|
+
7. @Entry
|
|
164
|
+
8. @Component
|
|
165
|
+
9. struct CompV1 {
|
|
166
|
+
10. @State observedClass: ObservedClass = new ObservedClass();
|
|
167
|
+
|
|
168
|
+
12. build() {
|
|
169
|
+
13. Column() {
|
|
170
|
+
14. Text(`@State observedClass: ${this.observedClass.name}`)
|
|
171
|
+
15. .onClick(() => {
|
|
172
|
+
16. this.observedClass.name += '!'; // 刷新
|
|
173
|
+
17. })
|
|
174
|
+
18. // 调用UIUtils.enableV2Compatibility使V1的状态变量可在@ComponentV2中有观察能力。
|
|
175
|
+
19. CompV2({ observedClass: UIUtils.enableV2Compatibility(this.observedClass) })
|
|
176
|
+
20. }
|
|
177
|
+
21. }
|
|
178
|
+
22. }
|
|
179
|
+
|
|
180
|
+
24. @ComponentV2
|
|
181
|
+
25. struct CompV2 {
|
|
182
|
+
26. @Param observedClass: ObservedClass = new ObservedClass();
|
|
183
|
+
|
|
184
|
+
28. build() {
|
|
185
|
+
29. // V1状态变量在使能V2观察能力后,可以在V2观察第一层的变化
|
|
186
|
+
30. Text(`@Param observedClass: ${this.observedClass.name}`)
|
|
187
|
+
31. .onClick(() => {
|
|
188
|
+
32. this.observedClass.name += '!'; // 刷新
|
|
189
|
+
33. })
|
|
190
|
+
34. }
|
|
191
|
+
35. }
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
[StateMixedSceneJsV1V2Recommend.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneJsV1V2Recommend.ets#L15-L52)
|
|
195
|
+
|
|
196
|
+
**@Observed+@Track装饰的class**
|
|
197
|
+
|
|
198
|
+
class类被@Observed修饰,从V1向V2传递使用enableV2Compatibility接口装饰的变量。该变量@Track装饰的属性在V1和V2中均可观察,但非@Track装饰的属性,在V1的UI中使用会导致运行时错误,而在V2中虽不会报错,但UI不会响应更新。
|
|
199
|
+
|
|
200
|
+
下面的例子中:
|
|
201
|
+
|
|
202
|
+
* name是@Track装饰的属性,其在V1和V2均是可观察的。
|
|
203
|
+
* count是非@Track装饰的属性,其在V1和V2的UI中使用均是非法的。
|
|
204
|
+
|
|
205
|
+
+ 在V1中,如果将非@Track装饰的属性使用在UI中,是非法行为,会有运行时报错。
|
|
206
|
+
+ 在V2中,非@Track装饰的属性使用在UI不会有运行时报错,但不会响应更新。
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
210
|
+
|
|
211
|
+
3. @Observed
|
|
212
|
+
4. class ObservedClass {
|
|
213
|
+
5. @Track public name: string = 'a';
|
|
214
|
+
6. public count: number = 0;
|
|
215
|
+
7. }
|
|
216
|
+
|
|
217
|
+
9. @Entry
|
|
218
|
+
10. @Component
|
|
219
|
+
11. struct CompV1 {
|
|
220
|
+
12. @State observedClass: ObservedClass = new ObservedClass();
|
|
221
|
+
|
|
222
|
+
14. build() {
|
|
223
|
+
15. Column() {
|
|
224
|
+
16. Text(`@State observedClass: ${this.observedClass.name}`)
|
|
225
|
+
17. .onClick(() => {
|
|
226
|
+
18. this.observedClass.name += 'a'; // 触发刷新
|
|
227
|
+
19. })
|
|
228
|
+
20. // 调用UIUtils.enableV2Compatibility使V1的状态变量可在@ComponentV2中有观察能力。
|
|
229
|
+
21. CompV2({ observedClass: UIUtils.enableV2Compatibility(this.observedClass) })
|
|
230
|
+
22. }
|
|
231
|
+
23. }
|
|
232
|
+
24. }
|
|
233
|
+
|
|
234
|
+
26. @ComponentV2
|
|
235
|
+
27. struct CompV2 {
|
|
236
|
+
28. @Param observedClass: ObservedClass = new ObservedClass();
|
|
237
|
+
|
|
238
|
+
30. build() {
|
|
239
|
+
31. Column() {
|
|
240
|
+
32. // V1状态变量在使能V2观察能力后,可以在V2观察第一层的变化
|
|
241
|
+
33. Text(`@Param observedClass: ${this.observedClass.name}`)
|
|
242
|
+
34. .onClick(() => {
|
|
243
|
+
35. this.observedClass.name += '!'; // 刷新
|
|
244
|
+
36. })
|
|
245
|
+
|
|
246
|
+
38. // 使用非@Track的变量在V2中不会崩溃,但不会响应更新
|
|
247
|
+
39. Text(`count: ${this.observedClass.count}`).onClick(() => {
|
|
248
|
+
40. this.observedClass.count++; // 不触发刷新
|
|
249
|
+
41. })
|
|
250
|
+
42. }
|
|
251
|
+
43. }
|
|
252
|
+
44. }
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
[StateMixedSceneObservedClassV1V2.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneObservedClassV1V2.ets#L15-L60)
|
|
256
|
+
|
|
257
|
+
### 传递内置类型(V1->V2)
|
|
258
|
+
|
|
259
|
+
以Array为例。建议调用enableV2Compatibility和makeV1Observed,避免造成V1和V2双重代理的问题。
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
263
|
+
|
|
264
|
+
3. @Entry
|
|
265
|
+
4. @Component
|
|
266
|
+
5. struct ArrayCompV1 {
|
|
267
|
+
6. @State arr: Array<number> = UIUtils.makeV1Observed([1, 2, 3]);
|
|
268
|
+
|
|
269
|
+
8. build() {
|
|
270
|
+
9. Column() {
|
|
271
|
+
10. Text(`V1 ${this.arr[0]}`).onClick(() => {
|
|
272
|
+
11. // 点击触发ArrayCompV1和ArrayCompV2变化
|
|
273
|
+
12. this.arr[0]++;
|
|
274
|
+
13. })
|
|
275
|
+
14. // 传递给V2时,发现当前代理是makeV1Observed包装的,且使能V2观察能力
|
|
276
|
+
15. // 在ArrayCompV2中Param不会再次包装代理,避免双重代理的问题
|
|
277
|
+
16. ArrayCompV2({ arr: UIUtils.enableV2Compatibility(this.arr) })
|
|
278
|
+
17. }
|
|
279
|
+
18. .height('100%')
|
|
280
|
+
19. .width('100%')
|
|
281
|
+
20. }
|
|
282
|
+
21. }
|
|
283
|
+
|
|
284
|
+
23. @ComponentV2
|
|
285
|
+
24. struct ArrayCompV2 {
|
|
286
|
+
25. @Param arr: Array<number> = [1, 2, 3];
|
|
287
|
+
|
|
288
|
+
27. build() {
|
|
289
|
+
28. Column() {
|
|
290
|
+
29. Text(`V2 ${this.arr[0]}`).onClick(() => {
|
|
291
|
+
30. // 点击触发ArrayCompV1和ArrayCompV2变化
|
|
292
|
+
31. this.arr[0]++;
|
|
293
|
+
32. })
|
|
294
|
+
33. }
|
|
295
|
+
34. }
|
|
296
|
+
35. }
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
[StateMixedSceneBuiltTypeV1V2Recommend.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneBuiltTypeV1V2Recommend.ets#L15-L51)
|
|
300
|
+
|
|
301
|
+
### 传递二维数组(V1->V2)
|
|
302
|
+
|
|
303
|
+
下面的例子中:
|
|
304
|
+
|
|
305
|
+
* 使用makeV1Observed将二维数组的内层数组变成V1的状态变量。
|
|
306
|
+
* 在传递给V2子组件时,调用enableV2Compatibility,使其具有V2的观察能力,也避免V1V2的双重代理。
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
310
|
+
|
|
311
|
+
3. @ComponentV2
|
|
312
|
+
4. struct Item {
|
|
313
|
+
5. @Require @Param itemArr: Array<string>;
|
|
314
|
+
|
|
315
|
+
7. build() {
|
|
316
|
+
8. Row() {
|
|
317
|
+
9. ForEach(this.itemArr, (item: string, index: number) => {
|
|
318
|
+
10. Text(`${index}: ${item}`)
|
|
319
|
+
11. }, (item: string) => item + Math.random())
|
|
320
|
+
12. // 新增数组元素
|
|
321
|
+
13. Button('@Param push')
|
|
322
|
+
14. .onClick(() => {
|
|
323
|
+
15. this.itemArr.push('Param');
|
|
324
|
+
16. })
|
|
325
|
+
17. }
|
|
326
|
+
18. }
|
|
327
|
+
19. }
|
|
328
|
+
|
|
329
|
+
21. @Entry
|
|
330
|
+
22. @Component
|
|
331
|
+
23. struct IndexPage {
|
|
332
|
+
24. @State arr: Array<Array<string>> =
|
|
333
|
+
25. [UIUtils.makeV1Observed(['apple']), UIUtils.makeV1Observed(['banana']), UIUtils.makeV1Observed(['orange'])];
|
|
334
|
+
|
|
335
|
+
27. build() {
|
|
336
|
+
28. Column() {
|
|
337
|
+
29. ForEach(this.arr, (itemArr: Array<string>) => {
|
|
338
|
+
30. Item({ itemArr: UIUtils.enableV2Compatibility(itemArr) })
|
|
339
|
+
31. }, (itemArr: Array<string>) => JSON.stringify(itemArr) + Math.random())
|
|
340
|
+
32. Divider()
|
|
341
|
+
33. // 数组arr[0]新增元素
|
|
342
|
+
34. Button('@State push two-dimensional array item')
|
|
343
|
+
35. .onClick(() => {
|
|
344
|
+
36. this.arr[0].push('strawberry');
|
|
345
|
+
37. })
|
|
346
|
+
38. // 数组arr新增元素
|
|
347
|
+
39. Button('@State push array item')
|
|
348
|
+
40. .onClick(() => {
|
|
349
|
+
41. this.arr.push(UIUtils.makeV1Observed(['pear']));
|
|
350
|
+
42. })
|
|
351
|
+
43. // 修改数组项arr[0][0]的值
|
|
352
|
+
44. Button('@State change two-dimensional array first item')
|
|
353
|
+
45. .onClick(() => {
|
|
354
|
+
46. this.arr[0][0] = 'APPLE';
|
|
355
|
+
47. })
|
|
356
|
+
48. // 修改数组arr的第一个元素
|
|
357
|
+
49. Button('@State change array first item')
|
|
358
|
+
50. .onClick(() => {
|
|
359
|
+
51. this.arr[0] = UIUtils.makeV1Observed(['watermelon']);
|
|
360
|
+
52. })
|
|
361
|
+
53. }
|
|
362
|
+
54. }
|
|
363
|
+
55. }
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
[StateMixedSceneTwoBitArrayV1V2.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneTwoBitArrayV1V2.ets#L15-L70)
|
|
367
|
+
|
|
368
|
+
### 传递嵌套类型(V1->V2)
|
|
369
|
+
|
|
370
|
+
开发者在状态管理V1中基于@Observed和@ObjectLink实现深度观测,以下代码示例是嵌套场景:
|
|
371
|
+
|
|
372
|
+
普通outer类在传递给V2子组件NestedClassV2时,调用enableV2Compatibility,使其具有V2的观察能力。如果开发者在传递给V2时没有调用enableV2Compatibility,则@Param无法观察对象的属性。
|
|
373
|
+
|
|
374
|
+
```
|
|
375
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
376
|
+
|
|
377
|
+
3. class ArrayItem {
|
|
378
|
+
4. public value: number = 0;
|
|
379
|
+
|
|
380
|
+
6. constructor(value: number) {
|
|
381
|
+
7. this.value = value;
|
|
382
|
+
8. }
|
|
383
|
+
9. }
|
|
384
|
+
|
|
385
|
+
11. class Inner {
|
|
386
|
+
12. public innerValue: string = 'inner';
|
|
387
|
+
13. public arr: Array<ArrayItem>;
|
|
388
|
+
|
|
389
|
+
15. constructor(arr: Array<ArrayItem>) {
|
|
390
|
+
16. this.arr = arr;
|
|
391
|
+
17. }
|
|
392
|
+
18. }
|
|
393
|
+
|
|
394
|
+
20. class Outer {
|
|
395
|
+
21. @Track public outerValue: string = 'outer';
|
|
396
|
+
22. @Track public inner: Inner;
|
|
397
|
+
|
|
398
|
+
24. constructor(inner: Inner) {
|
|
399
|
+
25. this.inner = inner;
|
|
400
|
+
26. }
|
|
401
|
+
27. }
|
|
402
|
+
|
|
403
|
+
29. @Entry
|
|
404
|
+
30. @Component
|
|
405
|
+
31. struct NestedClassV1 {
|
|
406
|
+
32. // 需保证每一层都是V1的状态变量
|
|
407
|
+
33. @State outer: Outer =
|
|
408
|
+
34. UIUtils.makeV1Observed(new Outer(
|
|
409
|
+
35. UIUtils.makeV1Observed(new Inner(UIUtils.makeV1Observed([
|
|
410
|
+
36. UIUtils.makeV1Observed(new ArrayItem(1)),
|
|
411
|
+
37. UIUtils.makeV1Observed(new ArrayItem(2))
|
|
412
|
+
38. ])))
|
|
413
|
+
39. ));
|
|
414
|
+
|
|
415
|
+
41. build() {
|
|
416
|
+
42. Column() {
|
|
417
|
+
43. Text(`@State outer.outerValue can update ${this.outer.outerValue}`)
|
|
418
|
+
44. .fontSize(20)
|
|
419
|
+
45. .onClick(() => {
|
|
420
|
+
46. // @State可以观察第一层的变化
|
|
421
|
+
47. // 变化会通知@ObjectLink和@Param刷新
|
|
422
|
+
48. this.outer.outerValue += '!';
|
|
423
|
+
49. })
|
|
424
|
+
|
|
425
|
+
51. Text(`@State outer.inner.innerValue cannot update ${this.outer.inner.innerValue}`)
|
|
426
|
+
52. .fontSize(20)
|
|
427
|
+
53. .onClick(() => {
|
|
428
|
+
54. // @State无法观察第二层的变化
|
|
429
|
+
55. // 但该变化会被@ObjectLink和@Param观察
|
|
430
|
+
56. this.outer.inner.innerValue += '!';
|
|
431
|
+
57. })
|
|
432
|
+
58. // 将inner传递给@ObjectLink可观察inner属性的变化
|
|
433
|
+
59. NestedClassV1ObjectLink({ inner: this.outer.inner })
|
|
434
|
+
60. // 将开启enableV2Compatibility的数据传给V2
|
|
435
|
+
61. NestedClassV2({ outer: UIUtils.enableV2Compatibility(this.outer) })
|
|
436
|
+
62. }
|
|
437
|
+
63. .height('100%')
|
|
438
|
+
64. .width('100%')
|
|
439
|
+
65. }
|
|
440
|
+
66. }
|
|
441
|
+
|
|
442
|
+
68. @Component
|
|
443
|
+
69. struct NestedClassV1ObjectLink {
|
|
444
|
+
70. @ObjectLink inner: Inner;
|
|
445
|
+
|
|
446
|
+
72. build() {
|
|
447
|
+
73. Text(`@ObjectLink inner.innerValue can update ${this.inner.innerValue}`)
|
|
448
|
+
74. .fontSize(20)
|
|
449
|
+
75. .onClick(() => {
|
|
450
|
+
76. // 可以触发刷新,和@Param是同一个对象的引用,@Param也会进行刷新
|
|
451
|
+
77. this.inner.innerValue += '!';
|
|
452
|
+
78. })
|
|
453
|
+
79. }
|
|
454
|
+
80. }
|
|
455
|
+
|
|
456
|
+
82. @ComponentV2
|
|
457
|
+
83. struct NestedClassV2 {
|
|
458
|
+
84. @Require @Param outer: Outer;
|
|
459
|
+
|
|
460
|
+
86. build() {
|
|
461
|
+
87. Column() {
|
|
462
|
+
88. Text(`@Param outer.outerValue can update ${this.outer.outerValue}`)
|
|
463
|
+
89. .fontSize(20)
|
|
464
|
+
90. .onClick(() => {
|
|
465
|
+
91. // 可以观察第一层的变化
|
|
466
|
+
92. this.outer.outerValue += '!';
|
|
467
|
+
93. })
|
|
468
|
+
94. Text(`@Param outer.inner.innerValue can update ${this.outer.inner.innerValue}`)
|
|
469
|
+
95. .fontSize(20)
|
|
470
|
+
96. .onClick(() => {
|
|
471
|
+
97. // 可以观察第二层的变化,和@ObjectLink是同一个对象的引用,也会触发刷新
|
|
472
|
+
98. this.outer.inner.innerValue += '!';
|
|
473
|
+
99. })
|
|
474
|
+
|
|
475
|
+
101. Repeat(this.outer.inner.arr)
|
|
476
|
+
102. .each((item: RepeatItem<ArrayItem>) => {
|
|
477
|
+
103. Text(`@Param outer.inner.arr index: ${item.index} item: ${item.item.value}`)
|
|
478
|
+
104. })
|
|
479
|
+
|
|
480
|
+
106. Button('@Param push').onClick(() => {
|
|
481
|
+
107. // outer已经使能了V2观察能力,对于新增加的数据,则默认开启V2观察能力
|
|
482
|
+
108. this.outer.inner.arr.push(UIUtils.makeV1Observed(new ArrayItem(20)));
|
|
483
|
+
109. })
|
|
484
|
+
|
|
485
|
+
111. Button('@Param change the last Item').onClick(() => {
|
|
486
|
+
112. // 可以观察最后一个数组项的属性变化
|
|
487
|
+
113. this.outer.inner.arr[this.outer.inner.arr.length - 1].value++;
|
|
488
|
+
114. })
|
|
489
|
+
115. }
|
|
490
|
+
116. }
|
|
491
|
+
117. }
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
[StateMixedSceneNestedTypeV1V2.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneNestedTypeV1V2.ets#L15-L133)
|
|
495
|
+
|
|
496
|
+
以上例子刷新行为可总结为:
|
|
497
|
+
|
|
498
|
+
* @State仅能观察第一层的变化,如果要深度观察,需要传递给@ObjectLink。
|
|
499
|
+
* @State的第二层的改变,虽然不能带来本层的刷新,但会被@ObjectLink和@Param观察到,并触发它们关联组件的刷新。
|
|
500
|
+
* @ObjectLink和@Param是同一个对象的引用,其属性改变也会带来其他引用的刷新。
|
|
501
|
+
|
|
502
|
+
## V2中使用V1的自定义组件
|
|
503
|
+
|
|
504
|
+
### 传递class类型(V2->V1)
|
|
505
|
+
|
|
506
|
+
**普通class**
|
|
507
|
+
|
|
508
|
+
因为V1和V2观察能力不同,如果不调用UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())直接进行数据传递,则会造成不刷新或者刷新行为不一致的问题。
|
|
509
|
+
|
|
510
|
+
```
|
|
511
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
512
|
+
|
|
513
|
+
3. class ObservedClass {
|
|
514
|
+
4. public name: string = 'Tom';
|
|
515
|
+
5. }
|
|
516
|
+
|
|
517
|
+
7. @Entry
|
|
518
|
+
8. @ComponentV2
|
|
519
|
+
9. struct CompV2 {
|
|
520
|
+
10. @Local observedClass: ObservedClass = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed(new ObservedClass()));
|
|
521
|
+
|
|
522
|
+
12. build() {
|
|
523
|
+
13. Column() {
|
|
524
|
+
14. // @Local原本能力仅可观察自身
|
|
525
|
+
15. // 但是调用了UIUtils.makeV1Observed使其变成V1的状态变量,V1状态变量可观察第一层变化
|
|
526
|
+
16. // 又调用UIUtils.enableV2Compatibility使其在V2中可观察
|
|
527
|
+
17. // 所以当前可观察第一层属性的变化
|
|
528
|
+
18. Text(`@Local observedClass: ${this.observedClass.name}`)
|
|
529
|
+
19. .onClick(() => {
|
|
530
|
+
20. this.observedClass.name += '!'; // 刷新
|
|
531
|
+
21. })
|
|
532
|
+
22. // @ObjectLink可接收@Observed装饰class的实例或者makeV1Observed的返回值
|
|
533
|
+
23. CompV1({ observedClass: this.observedClass })
|
|
534
|
+
24. }
|
|
535
|
+
25. }
|
|
536
|
+
26. }
|
|
537
|
+
|
|
538
|
+
28. @Component
|
|
539
|
+
29. struct CompV1 {
|
|
540
|
+
30. @ObjectLink observedClass: ObservedClass;
|
|
541
|
+
|
|
542
|
+
32. build() {
|
|
543
|
+
33. // 在CompV1中可观察第一层的变化
|
|
544
|
+
34. Text(`@ObjectLink observedClass: ${this.observedClass.name}`)
|
|
545
|
+
35. .onClick(() => {
|
|
546
|
+
36. this.observedClass.name += '!'; // 刷新
|
|
547
|
+
37. })
|
|
548
|
+
38. }
|
|
549
|
+
39. }
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
[StateMixedSceneJsV2V1Recommend.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneJsV2V1Recommend.ets#L15-L55)
|
|
553
|
+
|
|
554
|
+
**@Observed+@Track装饰的class**
|
|
555
|
+
|
|
556
|
+
下面例子中:
|
|
557
|
+
|
|
558
|
+
* ObservedClass是@Observed装饰的class,所以传递给V1调用UIUtils.enableV2Compatibility时,无需再调用UIUtils.makeV1Observed。
|
|
559
|
+
* 只有@Track装饰的变量在V1和V2中可观察。非@Track的变量在V1中使用在UI上会有运行时报错,在V2中不会报错,但不会响应刷新。
|
|
560
|
+
|
|
561
|
+
```
|
|
562
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
563
|
+
|
|
564
|
+
3. @Observed
|
|
565
|
+
4. class ObservedClass {
|
|
566
|
+
5. @Track public name: string = 'a';
|
|
567
|
+
6. public count: number = 0;
|
|
568
|
+
7. }
|
|
569
|
+
|
|
570
|
+
9. @Entry
|
|
571
|
+
10. @ComponentV2
|
|
572
|
+
11. struct CompV1 {
|
|
573
|
+
12. @Local observedClass: ObservedClass = UIUtils.enableV2Compatibility(new ObservedClass());
|
|
574
|
+
|
|
575
|
+
14. build() {
|
|
576
|
+
15. Column() {
|
|
577
|
+
16. Text(`name: ${this.observedClass.name}`).onClick(() => {
|
|
578
|
+
17. // 触发刷新
|
|
579
|
+
18. this.observedClass.name += 'a';
|
|
580
|
+
19. })
|
|
581
|
+
20. // 使用非@Track的变量在V2中不会崩溃,但不响应更新
|
|
582
|
+
21. Text(`count: ${this.observedClass.count}`).onClick(() => {
|
|
583
|
+
22. this.observedClass.count++;
|
|
584
|
+
23. })
|
|
585
|
+
|
|
586
|
+
25. CompV2({ observedClass: this.observedClass })
|
|
587
|
+
26. }
|
|
588
|
+
27. }
|
|
589
|
+
28. }
|
|
590
|
+
|
|
591
|
+
30. @Component
|
|
592
|
+
31. struct CompV2 {
|
|
593
|
+
32. @ObjectLink observedClass: ObservedClass;
|
|
594
|
+
|
|
595
|
+
34. build() {
|
|
596
|
+
35. Column() {
|
|
597
|
+
36. Text(`count: ${this.observedClass.name}`).onClick(() => {
|
|
598
|
+
37. // 触发刷新
|
|
599
|
+
38. this.observedClass.name += 'a';
|
|
600
|
+
39. })
|
|
601
|
+
40. }
|
|
602
|
+
41. }
|
|
603
|
+
42. }
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
[StateMixedSceneObservedClassV2V1.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneObservedClassV2V1.ets#L15-L58)
|
|
607
|
+
|
|
608
|
+
### 传递内置类型(V2->V1)
|
|
609
|
+
|
|
610
|
+
如果在V2中定义@Local arr: Array<number> = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed([1, 2, 3])),由于用了@Local装饰器V2可以观察属性的变化。但是没有调用enableV2Compatibility和makeV1Observed,V1无法观察属性的变化。所以正确做法调用UIUtils.enableV2Compatibility(UIUtils.makeV1Observed()),使V1中可以观察属性的变化。
|
|
611
|
+
|
|
612
|
+
```
|
|
613
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
614
|
+
|
|
615
|
+
3. @Entry
|
|
616
|
+
4. @ComponentV2
|
|
617
|
+
5. struct ArrayCompV2 {
|
|
618
|
+
6. @Local arr: Array<number> = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed([1, 2, 3]));
|
|
619
|
+
|
|
620
|
+
8. build() {
|
|
621
|
+
9. Column() {
|
|
622
|
+
10. Text(`V2 ${this.arr[0]}`).fontSize(20).onClick(() => {
|
|
623
|
+
11. // 点击触发V2变化,且同步给V1 @ObjectLink
|
|
624
|
+
12. this.arr[0]++;
|
|
625
|
+
13. })
|
|
626
|
+
14. ArrayCompV1({ arr: this.arr })
|
|
627
|
+
15. }
|
|
628
|
+
16. .height('100%')
|
|
629
|
+
17. .width('100%')
|
|
630
|
+
18. }
|
|
631
|
+
19. }
|
|
632
|
+
|
|
633
|
+
21. @Component
|
|
634
|
+
22. struct ArrayCompV1 {
|
|
635
|
+
23. @ObjectLink arr: Array<number>;
|
|
636
|
+
|
|
637
|
+
25. build() {
|
|
638
|
+
26. Column() {
|
|
639
|
+
27. Text(`V1 ${this.arr[0]}`).fontSize(20).onClick(() => {
|
|
640
|
+
28. // 点击触发V1变化,且双向同步回给V2
|
|
641
|
+
29. this.arr[0]++;
|
|
642
|
+
30. })
|
|
643
|
+
31. }
|
|
644
|
+
32. }
|
|
645
|
+
33. }
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
[StateMixedSceneBuiltTypeV2V1Recommend.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneBuiltTypeV2V1Recommend.ets#L15-L49)
|
|
649
|
+
|
|
650
|
+
### 传递二维数组(V2->V1)
|
|
651
|
+
|
|
652
|
+
下面的例子中:
|
|
653
|
+
|
|
654
|
+
* 使用makeV1Observed将二维数组的内层数组变成V1的状态变量。调用enableV2Compatibility,使其具有V2的观察能力,也避免V1和V2的双重代理。
|
|
655
|
+
* 在V1中,使用@ObjectLink接收二维数组的内层数组,因为其为makeV1Observed的返回值,所以点击Button('@ObjectLink push'),会正常响应刷新。
|
|
656
|
+
|
|
657
|
+
```
|
|
658
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
659
|
+
|
|
660
|
+
3. @Component
|
|
661
|
+
4. struct Item {
|
|
662
|
+
5. @ObjectLink itemArr: Array<string>;
|
|
663
|
+
|
|
664
|
+
7. build() {
|
|
665
|
+
8. Row() {
|
|
666
|
+
9. ForEach(this.itemArr, (item: string, index: number) => {
|
|
667
|
+
10. Text(`${index}: ${item}`)
|
|
668
|
+
11. }, (item: string) => item + Math.random())
|
|
669
|
+
12. // 新增数组元素
|
|
670
|
+
13. Button('@ObjectLink push')
|
|
671
|
+
14. .onClick(() => {
|
|
672
|
+
15. this.itemArr.push('ObjectLink');
|
|
673
|
+
16. })
|
|
674
|
+
17. }
|
|
675
|
+
18. }
|
|
676
|
+
19. }
|
|
677
|
+
|
|
678
|
+
21. @Entry
|
|
679
|
+
22. @ComponentV2
|
|
680
|
+
23. struct IndexPage {
|
|
681
|
+
24. @Local arr: Array<Array<string>> =
|
|
682
|
+
25. UIUtils.enableV2Compatibility(UIUtils.makeV1Observed([UIUtils.makeV1Observed(['apple']),
|
|
683
|
+
26. UIUtils.makeV1Observed(['banana']), UIUtils.makeV1Observed(['orange'])]));
|
|
684
|
+
|
|
685
|
+
28. build() {
|
|
686
|
+
29. Column() {
|
|
687
|
+
30. ForEach(this.arr, (itemArr: Array<string>) => {
|
|
688
|
+
31. Item({ itemArr: itemArr })
|
|
689
|
+
32. }, (itemArr: Array<string>) => JSON.stringify(itemArr) + Math.random())
|
|
690
|
+
33. Divider()
|
|
691
|
+
34. // 数组arr[0]新增元素
|
|
692
|
+
35. Button('@Local push two-dimensional array item')
|
|
693
|
+
36. .onClick(() => {
|
|
694
|
+
37. this.arr[0].push('strawberry');
|
|
695
|
+
38. })
|
|
696
|
+
39. // 数组arr新增元素
|
|
697
|
+
40. Button('@Local push array item')
|
|
698
|
+
41. .onClick(() => {
|
|
699
|
+
42. this.arr.push(UIUtils.makeV1Observed(['pear']));
|
|
700
|
+
43. })
|
|
701
|
+
44. // 修改数组项arr[0][0]的值
|
|
702
|
+
45. Button('@Local change two-dimensional array first item')
|
|
703
|
+
46. .onClick(() => {
|
|
704
|
+
47. this.arr[0][0] = 'APPLE';
|
|
705
|
+
48. })
|
|
706
|
+
49. // 修改数组arr的第一个元素
|
|
707
|
+
50. Button('@Local change array first item')
|
|
708
|
+
51. .onClick(() => {
|
|
709
|
+
52. this.arr[0] = UIUtils.makeV1Observed(['watermelon']);
|
|
710
|
+
53. })
|
|
711
|
+
54. }
|
|
712
|
+
55. }
|
|
713
|
+
56. }
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
[StateMixedSceneTwoBitArrayV2V1.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneTwoBitArrayV2V1.ets#L15-L71)
|
|
717
|
+
|
|
718
|
+
### 传递嵌套类型(V2->V1)
|
|
719
|
+
|
|
720
|
+
下面例子中:
|
|
721
|
+
|
|
722
|
+
* NestedClassV2中outer调用了UIUtils.enableV2Compatibility,且每一层都是UIUtils.makeV1Observed的返回值,所以outer在V2中有了深度观察的能力。
|
|
723
|
+
* V1中仅能观察第一层的变化,所以需要多层自定义组件,且每层都配合使用@ObjectLink来接收,从而实现深度观察能力。
|
|
724
|
+
|
|
725
|
+
```
|
|
726
|
+
1. import { UIUtils } from '@kit.ArkUI';
|
|
727
|
+
|
|
728
|
+
3. class ArrayItem {
|
|
729
|
+
4. public value: number = 0;
|
|
730
|
+
|
|
731
|
+
6. constructor(value: number) {
|
|
732
|
+
7. this.value = value;
|
|
733
|
+
8. }
|
|
734
|
+
9. }
|
|
735
|
+
|
|
736
|
+
11. class Inner {
|
|
737
|
+
12. public innerValue: string = 'inner';
|
|
738
|
+
13. public arr: Array<ArrayItem>;
|
|
739
|
+
|
|
740
|
+
15. constructor(arr: Array<ArrayItem>) {
|
|
741
|
+
16. this.arr = arr;
|
|
742
|
+
17. }
|
|
743
|
+
18. }
|
|
744
|
+
|
|
745
|
+
20. class Outer {
|
|
746
|
+
21. @Track public outerValue: string = 'out';
|
|
747
|
+
22. @Track public inner: Inner;
|
|
748
|
+
|
|
749
|
+
24. constructor(inner: Inner) {
|
|
750
|
+
25. this.inner = inner;
|
|
751
|
+
26. }
|
|
752
|
+
27. }
|
|
753
|
+
|
|
754
|
+
29. @Entry
|
|
755
|
+
30. @ComponentV2
|
|
756
|
+
31. struct NestedClassV2 {
|
|
757
|
+
32. // 需保证每一层都是V1的状态变量
|
|
758
|
+
33. @Local outer: Outer = UIUtils.enableV2Compatibility(
|
|
759
|
+
34. UIUtils.makeV1Observed(new Outer(
|
|
760
|
+
35. UIUtils.makeV1Observed(new Inner(UIUtils.makeV1Observed([
|
|
761
|
+
36. UIUtils.makeV1Observed(new ArrayItem(1)),
|
|
762
|
+
37. UIUtils.makeV1Observed(new ArrayItem(2))
|
|
763
|
+
38. ])))
|
|
764
|
+
39. )));
|
|
765
|
+
|
|
766
|
+
41. build() {
|
|
767
|
+
42. Column() {
|
|
768
|
+
43. Text(`@Local outer.outerValue can update ${this.outer.outerValue}`)
|
|
769
|
+
44. .fontSize(20)
|
|
770
|
+
45. .onClick(() => {
|
|
771
|
+
46. // 可观察第一层的变化
|
|
772
|
+
47. this.outer.outerValue += '!';
|
|
773
|
+
48. })
|
|
774
|
+
|
|
775
|
+
50. Text(`@Local outer.inner.innerValue can update ${this.outer.inner.innerValue}`)
|
|
776
|
+
51. .fontSize(20)
|
|
777
|
+
52. .onClick(() => {
|
|
778
|
+
53. // 可观察第二层的变化
|
|
779
|
+
54. this.outer.inner.innerValue += '!';
|
|
780
|
+
55. })
|
|
781
|
+
56. // 将inner传递给@ObjectLink可观察inner属性的变化
|
|
782
|
+
57. NestedClassV1ObjectLink({ inner: this.outer.inner })
|
|
783
|
+
58. }
|
|
784
|
+
59. .height('100%')
|
|
785
|
+
60. .width('100%')
|
|
786
|
+
61. }
|
|
787
|
+
62. }
|
|
788
|
+
|
|
789
|
+
64. @Component
|
|
790
|
+
65. struct NestedClassV1ObjectLink {
|
|
791
|
+
66. @ObjectLink inner: Inner;
|
|
792
|
+
|
|
793
|
+
68. build() {
|
|
794
|
+
69. Column() {
|
|
795
|
+
70. Text(`@ObjectLink inner.innerValue can update ${this.inner.innerValue}`)
|
|
796
|
+
71. .fontSize(20)
|
|
797
|
+
72. .onClick(() => {
|
|
798
|
+
73. // 可以触发刷新
|
|
799
|
+
74. this.inner.innerValue += '!';
|
|
800
|
+
75. })
|
|
801
|
+
76. NestedClassV1ObjectLinkArray({ arr: this.inner.arr })
|
|
802
|
+
77. }
|
|
803
|
+
78. }
|
|
804
|
+
79. }
|
|
805
|
+
|
|
806
|
+
81. @Component
|
|
807
|
+
82. struct NestedClassV1ObjectLinkArray {
|
|
808
|
+
83. @ObjectLink arr: Array<ArrayItem>;
|
|
809
|
+
|
|
810
|
+
85. build() {
|
|
811
|
+
86. Column() {
|
|
812
|
+
87. ForEach(this.arr, (item: ArrayItem) => {
|
|
813
|
+
88. NestedClassV1ObjectLinkArrayItem({ item: item })
|
|
814
|
+
89. }, (item: ArrayItem, index: number) => {
|
|
815
|
+
90. return item.value.toString() + index.toString();
|
|
816
|
+
91. })
|
|
817
|
+
|
|
818
|
+
93. Button('@ObjectLink push').onClick(() => {
|
|
819
|
+
94. this.arr.push(UIUtils.makeV1Observed(new ArrayItem(20)));
|
|
820
|
+
95. })
|
|
821
|
+
|
|
822
|
+
97. Button('@ObjectLink change the last Item').onClick(() => {
|
|
823
|
+
98. // 在NestedClassV1ObjectLinkArrayItem中可以观察最后一个数组项的属性变化
|
|
824
|
+
99. this.arr[this.arr.length - 1].value++;
|
|
825
|
+
100. })
|
|
826
|
+
101. }
|
|
827
|
+
102. }
|
|
828
|
+
103. }
|
|
829
|
+
|
|
830
|
+
105. @Component
|
|
831
|
+
106. struct NestedClassV1ObjectLinkArrayItem {
|
|
832
|
+
107. @ObjectLink item: ArrayItem;
|
|
833
|
+
|
|
834
|
+
109. build() {
|
|
835
|
+
110. Text(`@ObjectLink outer.inner.arr item: ${this.item.value}`)
|
|
836
|
+
111. }
|
|
837
|
+
112. }
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
[StateMixedSceneNestedTypeV2V1.ets](https://gitcode.com/HarmonyOS_Samples/guide-snippets/blob/HarmonyOS-feature-20260402/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneNestedTypeV2V1.ets#L15-L128)
|