android2harmony 0.1.7 → 0.1.8

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.
Files changed (226) hide show
  1. package/agents/api-analyzer.md +113 -0
  2. package/agents/app-action.md +122 -0
  3. package/agents/code-reviewer.md +191 -295
  4. package/agents/coder.md +377 -0
  5. package/agents/self-tester.md +8 -8
  6. package/agents/spec-designer.md +56 -0
  7. package/package.json +1 -1
  8. package/skills/a2h-app-req-gen/SKILL.md +174 -0
  9. package/skills/a2h-app-req-gen/references/spec-handoff.md +99 -0
  10. package/skills/a2h-app-req-gen/references/subagent-render.md +115 -0
  11. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/build.gradle.kts +41 -0
  12. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle/wrapper/gradle-wrapper.jar +0 -0
  13. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle/wrapper/gradle-wrapper.properties +8 -0
  14. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle.properties +3 -0
  15. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradlew +251 -0
  16. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradlew.bat +94 -0
  17. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/settings.gradle.kts +17 -0
  18. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawAnalysisDetector.java +1911 -0
  19. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawIssueRegistry.java +37 -0
  20. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawJson.java +146 -0
  21. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawLocation.java +96 -0
  22. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawRecordWriter.java +227 -0
  23. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry +1 -0
  24. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/resources/dev/reqgen/analyzer/jvm/raw-record-v1.schema.json +93 -0
  25. package/skills/a2h-app-req-gen/scripts/reqgen/assets/dashboard.html +151 -0
  26. package/skills/a2h-app-req-gen/scripts/reqgen/gradle/reqgen-lint.init.gradle +60 -0
  27. package/skills/a2h-app-req-gen/scripts/reqgen/gradle/reqgen-model.init.gradle +204 -0
  28. package/skills/a2h-app-req-gen/scripts/reqgen/package.json +14 -0
  29. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/backend.js +323 -0
  30. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/cli.js +811 -0
  31. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/gap-audit-link.js +62 -0
  32. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/index.js +66 -0
  33. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/merge.js +605 -0
  34. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/name-trace.js +153 -0
  35. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/orchestrate.js +1324 -0
  36. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/output-parse.js +50 -0
  37. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/overview.js +10 -0
  38. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/pool.js +23 -0
  39. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/post-merge-fix.js +146 -0
  40. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompt-loader.js +51 -0
  41. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompt.js +967 -0
  42. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompts.md +301 -0
  43. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/serve.js +78 -0
  44. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/short-id.js +46 -0
  45. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/snapshot.js +267 -0
  46. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/types.js +1 -0
  47. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/validate.js +122 -0
  48. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/callback-call-sites.js +62 -0
  49. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/gap-audit/build.js +1291 -0
  50. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/gap-audit/index.js +1 -0
  51. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/area-ownership.js +392 -0
  52. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/build.js +1995 -0
  53. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/callback-flow.js +277 -0
  54. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/component-variants.js +725 -0
  55. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/index.js +15 -0
  56. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/index.js +12 -0
  57. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/policy.js +469 -0
  58. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/traceability.js +468 -0
  59. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/req-model/build.js +1066 -0
  60. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/req-model/index.js +1 -0
  61. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/android-interaction-registry.js +174 -0
  62. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/android.js +1062 -0
  63. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/area-titles.js +678 -0
  64. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/builder.js +350 -0
  65. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose-api-registry.js +395 -0
  66. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose-call-sites.js +2008 -0
  67. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose.js +9059 -0
  68. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/dynamic-repeated-call-sites.js +529 -0
  69. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/index.js +1 -0
  70. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/interaction-effects.js +1149 -0
  71. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/jvm.js +6272 -0
  72. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/normalize.js +33 -0
  73. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/pending-intents.js +565 -0
  74. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/resource-id.js +42 -0
  75. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/route-state-variants.js +781 -0
  76. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/state.js +234 -0
  77. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/types.js +1 -0
  78. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/extract.js +40 -0
  79. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/index.js +6 -0
  80. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/manifest.js +513 -0
  81. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/resources.js +398 -0
  82. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/types.js +1 -0
  83. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/views.js +447 -0
  84. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/xml-parser.js +175 -0
  85. package/skills/a2h-app-req-gen/scripts/reqgen/src/cli.js +398 -0
  86. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/area-graph.js +1 -0
  87. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/artifact.js +1 -0
  88. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/common.js +16 -0
  89. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/diagnostic.js +10 -0
  90. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/gap-audit.js +14 -0
  91. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/index.js +11 -0
  92. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/name-traceability.js +26 -0
  93. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/raw-fact.js +40 -0
  94. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/req-model.js +1 -0
  95. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/run.js +19 -0
  96. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/semantic-completeness.js +11 -0
  97. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/source-facts.js +1 -0
  98. package/skills/a2h-app-req-gen/scripts/reqgen/src/core/output-guard.js +41 -0
  99. package/skills/a2h-app-req-gen/scripts/reqgen/src/core/stable-id.js +92 -0
  100. package/skills/a2h-app-req-gen/scripts/reqgen/src/dashboard-cli.js +169 -0
  101. package/skills/a2h-app-req-gen/scripts/reqgen/src/diagnostics.js +104 -0
  102. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump/dump.js +1028 -0
  103. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump/index.js +1 -0
  104. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump-cli.js +251 -0
  105. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/artifacts.js +49 -0
  106. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/index.js +18 -0
  107. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/quality-report.js +125 -0
  108. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/render.js +353 -0
  109. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/types.js +2 -0
  110. package/skills/a2h-app-req-gen/scripts/reqgen/src/graph/paths.js +474 -0
  111. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/index.js +15 -0
  112. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/protocol.js +408 -0
  113. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/runner.js +452 -0
  114. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/index.js +8 -0
  115. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/output.js +165 -0
  116. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/run-stage1.js +891 -0
  117. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/discovery.js +299 -0
  118. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/gradle-model.js +358 -0
  119. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/gradle-runner.js +165 -0
  120. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/resource-profile.js +60 -0
  121. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/types.js +1 -0
  122. package/skills/a2h-app-req-gen/scripts/reqgen/src/spec-handoff-cli.js +151 -0
  123. package/skills/a2h-app-req-gen/scripts/reqgen/src/spec-handoff.js +1004 -0
  124. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-cli.js +109 -0
  125. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-input.js +419 -0
  126. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-name-trace-input.js +95 -0
  127. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/area-graph.js +444 -0
  128. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/index.js +7 -0
  129. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/req-model.js +580 -0
  130. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/req-text.js +195 -0
  131. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/semantic-area-graph.js +1431 -0
  132. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/types.js +1 -0
  133. package/skills/a2h-app-req-gen/scripts/reqgen-audit.mjs +298 -0
  134. package/skills/a2h-app-req-gen/scripts/reqgen-selfcheck.mjs +555 -0
  135. package/skills/a2h-code-review/SKILL.md +379 -0
  136. package/skills/{hmos-integration-test → a2h-integration-test}/README.md +6 -6
  137. package/skills/{hmos-integration-test → a2h-integration-test}/SKILL.md +6 -6
  138. package/skills/{hmos-integration-test → a2h-integration-test}/scripts/report-tool.mjs +1 -1
  139. package/skills/a2h-spec-design/SKILL.md +330 -0
  140. package/skills/a2h-spec-design/scripts/inspect_spec_design_inputs.mjs +207 -0
  141. package/skills/a2h-spec-design/scripts/move_spec_technical_reference.mjs +198 -0
  142. package/skills/a2h-spec-design/scripts/validate_spec_design_output.mjs +256 -0
  143. package/skills/a2h-spec-generate/SKILL.md +696 -0
  144. package/skills/a2h-spec-generate/references/trace-template.md +115 -0
  145. package/skills/a2h-spec-generate/scripts/parse_requirements.mjs +537 -0
  146. package/skills/a2h-spec-generate/template/REQ.txt +22 -0
  147. package/skills/a2h-spec-generate/template/REQ.xlsx +0 -0
  148. package/skills/a2h-spec-implement/SKILL.md +548 -0
  149. package/skills/a2h-spec-implement/references/harmony-pitfalls.md +186 -0
  150. package/skills/a2h-spec-implement/references/l1-unit-test.md +185 -0
  151. package/skills/a2h-spec-implement/references/l3-e2e-uitest.md +167 -0
  152. package/skills/a2h-spec-implement/references/test-core.md +132 -0
  153. package/skills/a2h-spec-implement/rules/arkts/arkts-standards.md +184 -0
  154. package/skills/a2h-spec-implement/rules/arkts/conventions/coding-style.md +96 -0
  155. package/skills/a2h-spec-implement/rules/arkts/conventions/security.md +126 -0
  156. package/skills/a2h-spec-implement/rules/arkts/language/arkts-rules.md +650 -0
  157. package/skills/a2h-spec-implement/rules/arkts/language/arkui-structure-rules.md +173 -0
  158. package/skills/a2h-spec-implement/rules/arkts/language/ts-to-arkts-rewrites.md +58 -0
  159. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@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
  160. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@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
  161. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@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
  162. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@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
  163. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@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
  164. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@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
  165. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@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
  166. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/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
  167. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/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
  168. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/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
  169. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/MVVM/346/250/241/345/274/217/357/274/210V1/357/274/211.md +911 -0
  170. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/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
  171. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1//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
  172. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/!!/350/257/255/346/263/225/357/274/232/345/217/214/345/220/221/347/273/221/345/256/232.md +216 -0
  173. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@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 +442 -0
  174. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@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 +169 -0
  175. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@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 +763 -0
  176. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@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 +2088 -0
  177. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@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 +1258 -0
  178. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Once/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 +175 -0
  179. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Param/357/274/232/347/273/204/344/273/266/345/244/226/351/203/250/350/276/223/345/205/245.md +850 -0
  180. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@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 +862 -0
  181. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@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 +110 -0
  182. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/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 +301 -0
  183. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/MVVM/346/250/241/345/274/217/357/274/210V2/357/274/211.md +1411 -0
  184. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/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 +1392 -0
  185. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/getTarget/346/216/245/345/217/243/357/274/232/350/216/267/345/217/226/347/212/266/346/200/201/347/256/241/347/220/206/346/241/206/346/236/266/344/273/243/347/220/206/345/211/215/347/232/204/345/216/237/345/247/213/345/257/271/350/261/241.md +288 -0
  186. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/makeObserved/346/216/245/345/217/243/357/274/232/345/260/206/351/235/236/350/247/202/345/257/237/346/225/260/346/215/256/345/217/230/344/270/272/345/217/257/350/247/202/345/257/237/346/225/260/346/215/256.md +768 -0
  187. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2//347/212/266/346/200/201/347/256/241/347/220/206V1/345/222/214V2/346/267/267/347/224/250/346/214/207/345/257/274/357/274/210API version 19/345/217/212/344/271/213/345/220/216/357/274/211.md" +829 -0
  188. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2//347/212/266/346/200/201/347/256/241/347/220/206/346/246/202/350/277/260.md +184 -0
  189. package/skills/a2h-spec-implement/rules/arkts/ui/component-cookbook.md +431 -0
  190. package/skills/a2h-spec-implement/rules/arkts/ui/state-management.md +152 -0
  191. package/skills/a2h-spec-implement/rules/arkts/ui/ui-quality.md +67 -0
  192. package/skills/a2h-spec-implement/rules/arkts/ui/ui-runtime-diagnosis.md +32 -0
  193. package/skills/a2h-spec-implement/rules/pipeline/build/package-set-collection.md +43 -0
  194. package/skills/a2h-spec-implement/scripts/_lib/common.mjs +97 -0
  195. package/skills/a2h-spec-implement/scripts/_lib/config.mjs +70 -0
  196. package/skills/a2h-spec-implement/scripts/_lib/lessons_cli.mjs +48 -0
  197. package/skills/a2h-spec-implement/scripts/build_lessons.mjs +24 -0
  198. package/skills/a2h-spec-implement/scripts/code_pattern_lessons.mjs +26 -0
  199. package/skills/a2h-spec-implement/scripts/device_ui.mjs +433 -0
  200. package/skills/a2h-spec-implement/scripts/device_ui_core.mjs +895 -0
  201. package/skills/a2h-spec-implement/scripts/ledger/aggregate_run.mjs +207 -0
  202. package/skills/a2h-spec-implement/scripts/manifest/emit_summary_line.mjs +37 -0
  203. package/skills/a2h-spec-implement/scripts/manifest/finalize_run.mjs +115 -0
  204. package/skills/a2h-spec-implement/scripts/manifest/render_final_summary.mjs +78 -0
  205. package/skills/a2h-spec-implement/scripts/manifest/root_mirror.mjs +137 -0
  206. package/skills/a2h-spec-implement/scripts/package.json +12 -0
  207. package/skills/a2h-spec-implement/scripts/state_propagation_check.mjs +676 -0
  208. package/skills/a2h-spec-implement/scripts/test/l2_run.mjs +244 -0
  209. package/skills/a2h-spec-implement/scripts/test/tp_coverage.mjs +231 -0
  210. package/skills/a2h-spec-implement/scripts/ui_memory.mjs +161 -0
  211. package/skills/a2h-spec-implement/scripts/utils/ensure_app.mjs +134 -0
  212. package/skills/a2h-ui-transfer/SKILL.md +2 -2
  213. package/skills/hmos-convert-pipeline/SKILL.md +7 -5
  214. package/skills/hmos-incremental-ui-align/README.md +7 -7
  215. package/skills/hmos-incremental-ui-align/SKILL.md +1 -1
  216. package/skills/hmos-incremental-ui-align/page_align.md +1 -1
  217. package/skills/hmos-spec-generate/SKILL.md +2 -2
  218. package/skills/hmos-spec-generate/scripts/parse_requirements.mjs +537 -0
  219. package/skills/hmos-fix-build-errors/SKILL.md +0 -266
  220. package/skills/hmos-fix-build-errors/references/arkts-strict-patterns.md +0 -219
  221. package/skills/hmos-fix-build-errors/references/known-patterns.md +0 -157
  222. package/skills/hmos-fix-build-errors/references/rdb-entity-pattern.md +0 -131
  223. package/skills/hmos-spec-generate/scripts/parse_requirements.ts +0 -515
  224. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/resolve-metadata-tool.mjs +0 -0
  225. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/self-test-runner.mjs +0 -0
  226. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/testcases-tool.mjs +0 -0
@@ -0,0 +1,829 @@
1
+ # 状态管理V1和V2混用指导(API version 19及之后)
2
+ <!--Kit: ArkUI-->
3
+ <!--Subsystem: ArkUI-->
4
+ <!--Owner: @liwenzhen3-->
5
+ <!--Designer: @zhangboren-->
6
+ <!--Tester: @TerryTsao-->
7
+ <!--Adviser: @zhang_yixin13-->
8
+
9
+ ## 概述
10
+
11
+ 为了帮助开发者顺利地向状态管理V2迁移,从API version 19开始,减少了对状态管理V1和V2混用场景的约束。具体变更可参考[限制条件](#限制条件)。同时提供新的方法[enableV2Compatibility](../../reference/apis-arkui/js-apis-stateManagement.md#enablev2compatibility19)和[makeV1Observed](../../reference/apis-arkui/js-apis-stateManagement.md#makev1observed19)来帮助开发者解决在迁移过程中遇到的混用问题。
12
+
13
+ > **说明:**
14
+ >
15
+ > 本文档中使用“->”表示变量的传递,比如“V1->V2”,表示V1状态变量向V2状态变量传递。
16
+
17
+
18
+ ## 限制条件
19
+
20
+ 1. V1装饰器不能和[@ObservedV2](./arkts-new-observedV2-and-trace.md)一起使用。因为\@ObservedV2/\@Trace有自己独立的观察能力,不仅可以在[@ComponentV2](./arkts-create-custom-components.md#componentv2)中使用,也可以独立在[@Component](./arkts-create-custom-components.md#component)中使用,状态管理框架不希望其观察能力和V1的观察能力混合使用,所以依旧维持禁止现状。
21
+
22
+ 2. V2->V1,V1不支持用装饰器接收\@ObservedV2装饰的class,否则编译报错。
23
+
24
+ 3. V1中[@Link](./arkts-link.md)遵循其原本初始化规则,只能被V1状态变量初始化,详情见[@Link初始化规则示意图](./arkts-link.md#变量的传递访问规则说明)。因为V1中[@Link](./arkts-link.md)仅能和V1状态变量建立双向同步关系,而V2中如果想实现双向同步,可以使用\@Param、\@Event,具体例子见[@Link -> @Param/@Event迁移场景](./arkts-v1-v2-migration-inner-component.md#link---paramevent)。
25
+
26
+
27
+ ## 新增接口
28
+
29
+ ### makeV1Observed
30
+
31
+ [makeV1Observed](../../reference/apis-arkui/js-apis-stateManagement.md#makev1observed19)将不可观察的对象包装成状态管理V1可观察的对象,能力等同于\@Observed,其返回值可初始化\@ObjectLink。
32
+
33
+ > **说明:**
34
+ >
35
+ > 从API version 19开始,开发者可以使用UIUtils中的makeV1Observed接口将不可观察的对象包装成状态管理V1可观察的对象。
36
+
37
+ **接口说明**
38
+ - makeV1Observed主要和enableV2Compatibility搭配使用,实现V2->V1的传递。
39
+ - makeV1Observed可将普通class、Array、Map、Set、Date类型转换为V1的状态变量,其能力等同于\@Observed,所以其返回值可以初始化\@ObjectLink。
40
+ - 如果makeV1Observed接受的数据已经是V1的状态变量,则返回自身,不做任何改变。
41
+ - makeV1Observed不会递归执行,仅会将第一层包装成V1的状态变量。
42
+
43
+ **限制条件**
44
+
45
+ <!--PR1-->
46
+ - 不支持[collections类型](../../reference/apis-arkts/arkts-apis-arkts-collections.md)和[@Sendable](../../arkts-utils/arkts-sendable.md)装饰的class。
47
+ <!--PR1End-->
48
+
49
+ - 不支持非object类型。
50
+
51
+ - 不支持undefined、null。
52
+
53
+ - 不支持\@ObservedV2、[makeObserved](../../reference/apis-arkui/js-apis-stateManagement.md#makeobserved)的返回值和V2装饰器装饰的built-in类型的变量(Array、Map、Set和Date)。
54
+
55
+
56
+ ### enableV2Compatibility
57
+
58
+ [enableV2Compatibility](../../reference/apis-arkui/js-apis-stateManagement.md#enablev2compatibility19)将V1的状态变量使能V2的观察能力,即让V1状态变量可以在\@ComponentV2中观察到变化。
59
+
60
+ > **说明:**
61
+ >
62
+ > 从API version 19开始,开发者可以使用UIUtils中的enableV2Compatibility接口将V1的状态变量兼容V2中使用。
63
+
64
+ **接口说明**
65
+
66
+ - 该接口主要应用于V1->V2的场景,V1的状态变量调用该接口后,传递到\@ComponentV2中,则可以在V2中观察到变化,从而实现数据的联动刷新。
67
+
68
+ - enableV2Compatibility只能作用于V1的状态变量。V1状态变量为V1装饰器装饰的变量,即\@Observed装饰的变量,或[@State](./arkts-state.md)、[@Prop](./arkts-prop.md)、[@Link](./arkts-link.md)、[@Provide](./arkts-provide-and-consume.md)、[@Consume](./arkts-provide-and-consume.md)和[@ObjectLink](./arkts-observed-and-objectlink.md)(\@ObjectLink需是\@Observed装饰的实例或者makeV1Observed的返回值)装饰的变量。否则,将返回入参自身。
69
+
70
+ - enableV2Compatibility会递归遍历class的所有属性,Array/Set/Map的所有子项,直到遇到非V1状态变量的数据,则停止当前分支的遍历。
71
+
72
+ **限制条件**
73
+
74
+ - 不支持非object类型。
75
+ - 不支持undefined、null。
76
+ - 不支持非V1的状态变量数据。
77
+ - 不支持\@ObservedV2、[makeObserved](../../reference/apis-arkui/js-apis-stateManagement.md#makeobserved)的返回值和V2装饰器装饰的built-in类型的变量(Array、Map、Set和Date)。
78
+
79
+ ## 混用规则
80
+
81
+ - V1->V2传递复杂类型数据,需要调用enableV2Compatibility,否则无法实现V1和V2的数据联动,建议在V2组件的构造处调用,否则当变量被整体赋值时,需要再次手动调用enableV2Compatibility。
82
+
83
+ ```ts
84
+ // 建议用法,this.state = new ObservedClass()时无需再调用UIUtils.enableV2Compatibility,减少代码量
85
+ SubComponentV2({param: UIUtils.enableV2Compatibility(this.state)})
86
+
87
+ // 不建议用法,state做整体赋值时,需要再次调用UIUtils.enableV2Compatibility
88
+ // 否则传递给SubComponentV2的V1变量是无法在V2中观察的
89
+ // @State state: ObservedClass = UIUtils.enableV2Compatibility(new ObservedClass());
90
+ // this.state = UIUtils.enableV2Compatibility(new ObservedClass());
91
+ SubComponentV2({param: this.state})
92
+ ```
93
+
94
+ - V2->V1传递复杂类型数据,在V2中优先声明成V1的状态变量数据,并调用UIUtils.enableV2Compatibility。因为在状态管理V1中,状态变量默认有观察第一层的能力,而状态管理V2仅有观察自身的能力,如果希望双方数据联动,则需要调用UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())拉齐双方的观察能力。
95
+
96
+ ```ts
97
+ // 建议用法
98
+ @Local unObservedClass: UnObservedClass = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed(new UnObservedClass()));
99
+
100
+ // 建议用法,ObservedClass是@Observed装饰的class
101
+ @Local observedClass: ObservedClass = UIUtils.enableV2Compatibility(new ObservedClass());
102
+ ```
103
+
104
+ - UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())不会改变V1和V2本身观察能力。
105
+ - 在V1中,UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())等于V1的观察能力,观察数据本身的赋值和第一层属性的赋值,无法深度观察,如果需要深度观察,则需要配合\@ObjectLink。
106
+ - 在V2中,UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())可以深度观察,但是需要每一层都是\@Observed装饰的class,或者是makeV1Observed的返回值。
107
+ - 不使用enableV2Compatibility和makeV1Observed会导致双重代理问题,使同一状态对象被V1和V2两套状态管理体系同时生成代理对象,从而引起监听逻辑冲突。
108
+
109
+ - 当数据已使用V2观察能力,即调用UIUtils.enableV2Compatibility后,会将新的数据默认使用V2观察能力,但需要开发者确保新增数据是\@Observed装饰的class,或者是makeV1Observed的返回值。完整例子可见[传递嵌套类型(V1->V2)](#传递嵌套类型v1-v2)、[传递嵌套类型(V2->V1)](#传递嵌套类型v2-v1)。
110
+ ```ts
111
+ let arr: Array<ArrayItem> = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed(new ArrayItem()));
112
+
113
+ arr.push(new ArrayItem()); // 新增数据不是V1状态变量,所以不会具有V2观察能力
114
+ arr.push(UIUtils.makeV1Observed(new ArrayItem())); // 新增数据是V1的状态变量,默认在V2中可观察
115
+ ```
116
+
117
+ - 对于built-in类型,如Array、Map、Set和Date,V1和V2都可以观察自身赋值和其API的调用所带来的变化。虽然开发者在不调用UIUtils.enableV2Compatibility时,也可以在一些简单场景下实现数据刷新,但是会带来双重代理导致性能较差的问题,所以建议开发者使用UIUtils.enableV2Compatibility(UIUtils.makeV1Observed()),具体例子见[传递内置类型(V1->V2)](#传递内置类型v1-v2)、[传递内置类型(V2->V1)](#传递内置类型v2-v1)。
118
+
119
+ - 对于有[@Track](./arkts-track.md)装饰属性的类,非\@Track装饰的属性在\@ComponentV2中使用不会崩溃,在\@Component中使用仍会崩溃。具体例子见[传递class类型(V1->V2)](#传递class类型v1-v2)、[传递class类型(V2->V1)](#传递class类型v2-v1)。
120
+
121
+ 开发者在使用这两个接口混用V1V2时,可遵循下图逻辑。
122
+
123
+ ![mix-usage](./figures/V1V2_mix_usage.png)
124
+
125
+
126
+ ## V1中使用V2的自定义组件
127
+
128
+
129
+ ### 传递class类型(V1->V2)
130
+
131
+ **普通class**
132
+
133
+ 以下代码中,V1的状态变量在传递给V2时,调用enableV2Compatibility接口,使V1的变量observedClass在V2组件中有观察能力。
134
+
135
+ <!-- @[state_mixed_scene_js_v1_v2_recommend](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneJsV1V2Recommend.ets) -->
136
+
137
+ ``` TypeScript
138
+ import { UIUtils } from '@kit.ArkUI';
139
+
140
+ class ObservedClass {
141
+ public name: string = 'Tom';
142
+ }
143
+
144
+ @Entry
145
+ @Component
146
+ struct CompV1 {
147
+ @State observedClass: ObservedClass = new ObservedClass();
148
+
149
+ build() {
150
+ Column() {
151
+ Text(`@State observedClass: ${this.observedClass.name}`)
152
+ .onClick(() => {
153
+ this.observedClass.name += '!'; // 刷新
154
+ })
155
+ // 调用UIUtils.enableV2Compatibility使V1的状态变量可在@ComponentV2中有观察能力。
156
+ CompV2({ observedClass: UIUtils.enableV2Compatibility(this.observedClass) })
157
+ }
158
+ }
159
+ }
160
+
161
+ @ComponentV2
162
+ struct CompV2 {
163
+ @Param observedClass: ObservedClass = new ObservedClass();
164
+
165
+ build() {
166
+ // V1状态变量在使能V2观察能力后,可以在V2观察第一层的变化
167
+ Text(`@Param observedClass: ${this.observedClass.name}`)
168
+ .onClick(() => {
169
+ this.observedClass.name += '!'; // 刷新
170
+ })
171
+ }
172
+ }
173
+ ```
174
+
175
+ **\@Observed+\@Track装饰的class**
176
+
177
+ class类被\@Observed修饰,从V1向V2传递使用enableV2Compatibility接口装饰的变量。该变量\@Track装饰的属性在V1和V2中均可观察,但非\@Track装饰的属性,在V1的UI中使用会导致运行时错误,而在V2中虽不会报错,但UI不会响应更新。
178
+
179
+ 下面的例子中:
180
+
181
+ - name是\@Track装饰的属性,其在V1和V2均是可观察的。
182
+
183
+ - count是非\@Track装饰的属性,其在V1和V2的UI中使用均是非法的。
184
+ - 在V1中,如果将非\@Track装饰的属性使用在UI中,是非法行为,会有运行时报错。
185
+ - 在V2中,非\@Track装饰的属性使用在UI不会有运行时报错,但不会响应更新。
186
+
187
+ <!-- @[state_mixed_scene_observed_class_v1_v2](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneObservedClassV1V2.ets) -->
188
+
189
+ ``` TypeScript
190
+ import { UIUtils } from '@kit.ArkUI';
191
+
192
+ @Observed
193
+ class ObservedClass {
194
+ @Track public name: string = 'a';
195
+ public count: number = 0;
196
+ }
197
+
198
+ @Entry
199
+ @Component
200
+ struct CompV1 {
201
+ @State observedClass: ObservedClass = new ObservedClass();
202
+
203
+ build() {
204
+ Column() {
205
+ Text(`@State observedClass: ${this.observedClass.name}`)
206
+ .onClick(() => {
207
+ this.observedClass.name += 'a'; // 触发刷新
208
+ })
209
+ // 调用UIUtils.enableV2Compatibility使V1的状态变量可在@ComponentV2中有观察能力。
210
+ CompV2({ observedClass: UIUtils.enableV2Compatibility(this.observedClass) })
211
+ }
212
+ }
213
+ }
214
+
215
+ @ComponentV2
216
+ struct CompV2 {
217
+ @Param observedClass: ObservedClass = new ObservedClass();
218
+
219
+ build() {
220
+ Column() {
221
+ // V1状态变量在使能V2观察能力后,可以在V2观察第一层的变化
222
+ Text(`@Param observedClass: ${this.observedClass.name}`)
223
+ .onClick(() => {
224
+ this.observedClass.name += '!'; // 刷新
225
+ })
226
+
227
+ // 使用非@Track的变量在V2中不会崩溃,但不会响应更新
228
+ Text(`count: ${this.observedClass.count}`).onClick(() => {
229
+ this.observedClass.count++; // 不触发刷新
230
+ })
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+
237
+ ### 传递内置类型(V1->V2)
238
+
239
+ 以Array为例。建议调用enableV2Compatibility和makeV1Observed,避免造成V1和V2双重代理的问题。
240
+
241
+ <!-- @[state_mixed_scene_built_type_v1_v2_recommend](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneBuiltTypeV1V2Recommend.ets) -->
242
+
243
+ ``` TypeScript
244
+ import { UIUtils } from '@kit.ArkUI';
245
+
246
+ @Entry
247
+ @Component
248
+ struct ArrayCompV1 {
249
+ @State arr: Array<number> = UIUtils.makeV1Observed([1, 2, 3]);
250
+
251
+ build() {
252
+ Column() {
253
+ Text(`V1 ${this.arr[0]}`).onClick(() => {
254
+ // 点击触发ArrayCompV1和ArrayCompV2变化
255
+ this.arr[0]++;
256
+ })
257
+ // 传递给V2时,发现当前代理是makeV1Observed包装的,且使能V2观察能力
258
+ // 在ArrayCompV2中Param不会再次包装代理,避免双重代理的问题
259
+ ArrayCompV2({ arr: UIUtils.enableV2Compatibility(this.arr) })
260
+ }
261
+ .height('100%')
262
+ .width('100%')
263
+ }
264
+ }
265
+
266
+ @ComponentV2
267
+ struct ArrayCompV2 {
268
+ @Param arr: Array<number> = [1, 2, 3];
269
+
270
+ build() {
271
+ Column() {
272
+ Text(`V2 ${this.arr[0]}`).onClick(() => {
273
+ // 点击触发ArrayCompV1和ArrayCompV2变化
274
+ this.arr[0]++;
275
+ })
276
+ }
277
+ }
278
+ }
279
+ ```
280
+
281
+
282
+ ### 传递二维数组(V1->V2)
283
+
284
+ 下面的例子中:
285
+
286
+ - 使用makeV1Observed将二维数组的内层数组变成V1的状态变量。
287
+ - 在传递给V2子组件时,调用enableV2Compatibility,使其具有V2的观察能力,也避免V1V2的双重代理。
288
+
289
+ <!-- @[state_mixed_scene_two_bit_array_v1_v2](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneTwoBitArrayV1V2.ets) -->
290
+
291
+ ``` TypeScript
292
+ import { UIUtils } from '@kit.ArkUI';
293
+
294
+ @ComponentV2
295
+ struct Item {
296
+ @Require @Param itemArr: Array<string>;
297
+
298
+ build() {
299
+ Row() {
300
+ ForEach(this.itemArr, (item: string, index: number) => {
301
+ Text(`${index}: ${item}`)
302
+ }, (item: string) => item + Math.random())
303
+ // 新增数组元素
304
+ Button('@Param push')
305
+ .onClick(() => {
306
+ this.itemArr.push('Param');
307
+ })
308
+ }
309
+ }
310
+ }
311
+
312
+ @Entry
313
+ @Component
314
+ struct IndexPage {
315
+ @State arr: Array<Array<string>> =
316
+ [UIUtils.makeV1Observed(['apple']), UIUtils.makeV1Observed(['banana']), UIUtils.makeV1Observed(['orange'])];
317
+
318
+ build() {
319
+ Column() {
320
+ ForEach(this.arr, (itemArr: Array<string>) => {
321
+ Item({ itemArr: UIUtils.enableV2Compatibility(itemArr) })
322
+ }, (itemArr: Array<string>) => JSON.stringify(itemArr) + Math.random())
323
+ Divider()
324
+ // 数组arr[0]新增元素
325
+ Button('@State push two-dimensional array item')
326
+ .onClick(() => {
327
+ this.arr[0].push('strawberry');
328
+ })
329
+ // 数组arr新增元素
330
+ Button('@State push array item')
331
+ .onClick(() => {
332
+ this.arr.push(UIUtils.makeV1Observed(['pear']));
333
+ })
334
+ // 修改数组项arr[0][0]的值
335
+ Button('@State change two-dimensional array first item')
336
+ .onClick(() => {
337
+ this.arr[0][0] = 'APPLE';
338
+ })
339
+ // 修改数组arr的第一个元素
340
+ Button('@State change array first item')
341
+ .onClick(() => {
342
+ this.arr[0] = UIUtils.makeV1Observed(['watermelon']);
343
+ })
344
+ }
345
+ }
346
+ }
347
+ ```
348
+
349
+
350
+ ### 传递嵌套类型(V1->V2)
351
+
352
+ 开发者在状态管理V1中基于\@Observed和\@ObjectLink实现深度观测,以下代码示例是嵌套场景:
353
+
354
+ 普通outer类在传递给V2子组件NestedClassV2时,调用enableV2Compatibility,使其具有V2的观察能力。如果开发者在传递给V2时没有调用enableV2Compatibility,则\@Param无法观察对象的属性。
355
+
356
+ <!-- @[state_mixed_scene_nested_type_v1_v2](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneNestedTypeV1V2.ets) -->
357
+
358
+ ``` TypeScript
359
+ import { UIUtils } from '@kit.ArkUI';
360
+
361
+ class ArrayItem {
362
+ public value: number = 0;
363
+
364
+ constructor(value: number) {
365
+ this.value = value;
366
+ }
367
+ }
368
+
369
+ class Inner {
370
+ public innerValue: string = 'inner';
371
+ public arr: Array<ArrayItem>;
372
+
373
+ constructor(arr: Array<ArrayItem>) {
374
+ this.arr = arr;
375
+ }
376
+ }
377
+
378
+ class Outer {
379
+ @Track public outerValue: string = 'outer';
380
+ @Track public inner: Inner;
381
+
382
+ constructor(inner: Inner) {
383
+ this.inner = inner;
384
+ }
385
+ }
386
+
387
+ @Entry
388
+ @Component
389
+ struct NestedClassV1 {
390
+ // 需保证每一层都是V1的状态变量
391
+ @State outer: Outer =
392
+ UIUtils.makeV1Observed(new Outer(
393
+ UIUtils.makeV1Observed(new Inner(UIUtils.makeV1Observed([
394
+ UIUtils.makeV1Observed(new ArrayItem(1)),
395
+ UIUtils.makeV1Observed(new ArrayItem(2))
396
+ ])))
397
+ ));
398
+
399
+ build() {
400
+ Column() {
401
+ Text(`@State outer.outerValue can update ${this.outer.outerValue}`)
402
+ .fontSize(20)
403
+ .onClick(() => {
404
+ // @State可以观察第一层的变化
405
+ // 变化会通知@ObjectLink和@Param刷新
406
+ this.outer.outerValue += '!';
407
+ })
408
+
409
+ Text(`@State outer.inner.innerValue cannot update ${this.outer.inner.innerValue}`)
410
+ .fontSize(20)
411
+ .onClick(() => {
412
+ // @State无法观察第二层的变化
413
+ // 但该变化会被@ObjectLink和@Param观察
414
+ this.outer.inner.innerValue += '!';
415
+ })
416
+ // 将inner传递给@ObjectLink可观察inner属性的变化
417
+ NestedClassV1ObjectLink({ inner: this.outer.inner })
418
+ // 将开启enableV2Compatibility的数据传给V2
419
+ NestedClassV2({ outer: UIUtils.enableV2Compatibility(this.outer) })
420
+ }
421
+ .height('100%')
422
+ .width('100%')
423
+ }
424
+ }
425
+
426
+ @Component
427
+ struct NestedClassV1ObjectLink {
428
+ @ObjectLink inner: Inner;
429
+
430
+ build() {
431
+ Text(`@ObjectLink inner.innerValue can update ${this.inner.innerValue}`)
432
+ .fontSize(20)
433
+ .onClick(() => {
434
+ // 可以触发刷新,和@Param是同一个对象的引用,@Param也会进行刷新
435
+ this.inner.innerValue += '!';
436
+ })
437
+ }
438
+ }
439
+
440
+ @ComponentV2
441
+ struct NestedClassV2 {
442
+ @Require @Param outer: Outer;
443
+
444
+ build() {
445
+ Column() {
446
+ Text(`@Param outer.outerValue can update ${this.outer.outerValue}`)
447
+ .fontSize(20)
448
+ .onClick(() => {
449
+ // 可以观察第一层的变化
450
+ this.outer.outerValue += '!';
451
+ })
452
+ Text(`@Param outer.inner.innerValue can update ${this.outer.inner.innerValue}`)
453
+ .fontSize(20)
454
+ .onClick(() => {
455
+ // 可以观察第二层的变化,和@ObjectLink是同一个对象的引用,也会触发刷新
456
+ this.outer.inner.innerValue += '!';
457
+ })
458
+
459
+ Repeat(this.outer.inner.arr)
460
+ .each((item: RepeatItem<ArrayItem>) => {
461
+ Text(`@Param outer.inner.arr index: ${item.index} item: ${item.item.value}`)
462
+ })
463
+
464
+ Button('@Param push').onClick(() => {
465
+ // outer已经使能了V2观察能力,对于新增加的数据,则默认开启V2观察能力
466
+ this.outer.inner.arr.push(UIUtils.makeV1Observed(new ArrayItem(20)));
467
+ })
468
+
469
+ Button('@Param change the last Item').onClick(() => {
470
+ // 可以观察最后一个数组项的属性变化
471
+ this.outer.inner.arr[this.outer.inner.arr.length - 1].value++;
472
+ })
473
+ }
474
+ }
475
+ }
476
+ ```
477
+
478
+ 以上例子刷新行为可总结为:
479
+
480
+ - \@State仅能观察第一层的变化,如果要深度观察,需要传递给\@ObjectLink。
481
+
482
+ - \@State的第二层的改变,虽然不能带来本层的刷新,但会被\@ObjectLink和\@Param观察到,并触发它们关联组件的刷新。
483
+
484
+ - \@ObjectLink和\@Param是同一个对象的引用,其属性改变也会带来其他引用的刷新。
485
+
486
+
487
+ ## V2中使用V1的自定义组件
488
+
489
+
490
+ ### 传递class类型(V2->V1)
491
+
492
+ **普通class**
493
+
494
+ 因为V1和V2观察能力不同,如果不调用UIUtils.enableV2Compatibility(UIUtils.makeV1Observed())直接进行数据传递,则会造成不刷新或者刷新行为不一致的问题。
495
+
496
+ <!-- @[state_mixed_scene_js_v2_v1_recommend](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneJsV2V1Recommend.ets) -->
497
+
498
+ ``` TypeScript
499
+ import { UIUtils } from '@kit.ArkUI';
500
+
501
+ class ObservedClass {
502
+ public name: string = 'Tom';
503
+ }
504
+
505
+ @Entry
506
+ @ComponentV2
507
+ struct CompV2 {
508
+ @Local observedClass: ObservedClass = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed(new ObservedClass()));
509
+
510
+ build() {
511
+ Column() {
512
+ // @Local原本能力仅可观察自身
513
+ // 但是调用了UIUtils.makeV1Observed使其变成V1的状态变量,V1状态变量可观察第一层变化
514
+ // 又调用UIUtils.enableV2Compatibility使其在V2中可观察
515
+ // 所以当前可观察第一层属性的变化
516
+ Text(`@Local observedClass: ${this.observedClass.name}`)
517
+ .onClick(() => {
518
+ this.observedClass.name += '!'; // 刷新
519
+ })
520
+ // @ObjectLink可接收@Observed装饰class的实例或者makeV1Observed的返回值
521
+ CompV1({ observedClass: this.observedClass })
522
+ }
523
+ }
524
+ }
525
+
526
+ @Component
527
+ struct CompV1 {
528
+ @ObjectLink observedClass: ObservedClass;
529
+
530
+ build() {
531
+ // 在CompV1中可观察第一层的变化
532
+ Text(`@ObjectLink observedClass: ${this.observedClass.name}`)
533
+ .onClick(() => {
534
+ this.observedClass.name += '!'; // 刷新
535
+ })
536
+ }
537
+ }
538
+ ```
539
+
540
+ **\@Observed+\@Track装饰的class**
541
+
542
+ 下面例子中:
543
+
544
+ - ObservedClass是\@Observed装饰的class,所以传递给V1调用UIUtils.enableV2Compatibility时,无需再调用UIUtils.makeV1Observed。
545
+ - 只有\@Track装饰的变量在V1和V2中可观察。非\@Track的变量在V1中使用在UI上会有运行时报错,在V2中不会报错,但不会响应刷新。
546
+
547
+ <!-- @[state_mixed_scene_observed_class_v2_v1](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneObservedClassV2V1.ets) -->
548
+
549
+ ``` TypeScript
550
+ import { UIUtils } from '@kit.ArkUI';
551
+
552
+ @Observed
553
+ class ObservedClass {
554
+ @Track public name: string = 'a';
555
+ public count: number = 0;
556
+ }
557
+
558
+ @Entry
559
+ @ComponentV2
560
+ struct CompV1 {
561
+ @Local observedClass: ObservedClass = UIUtils.enableV2Compatibility(new ObservedClass());
562
+
563
+ build() {
564
+ Column() {
565
+ Text(`name: ${this.observedClass.name}`).onClick(() => {
566
+ // 触发刷新
567
+ this.observedClass.name += 'a';
568
+ })
569
+ // 使用非@Track的变量在V2中不会崩溃,但不响应更新
570
+ Text(`count: ${this.observedClass.count}`).onClick(() => {
571
+ this.observedClass.count++;
572
+ })
573
+
574
+ CompV2({ observedClass: this.observedClass })
575
+ }
576
+ }
577
+ }
578
+
579
+ @Component
580
+ struct CompV2 {
581
+ @ObjectLink observedClass: ObservedClass;
582
+
583
+ build() {
584
+ Column() {
585
+ Text(`count: ${this.observedClass.name}`).onClick(() => {
586
+ // 触发刷新
587
+ this.observedClass.name += 'a';
588
+ })
589
+ }
590
+ }
591
+ }
592
+ ```
593
+
594
+
595
+ ### 传递内置类型(V2->V1)
596
+
597
+ 如果在V2中定义\@Local arr: Array\<number> = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed([1, 2, 3])),由于用了\@Local装饰器V2可以观察属性的变化。但是没有调用enableV2Compatibility和makeV1Observed,V1无法观察属性的变化。所以正确做法调用UIUtils.enableV2Compatibility(UIUtils.makeV1Observed()),使V1中可以观察属性的变化。
598
+
599
+ <!-- @[state_mixed_scene_built_type_v2_v1_recommend](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneBuiltTypeV2V1Recommend.ets) -->
600
+
601
+ ``` TypeScript
602
+ import { UIUtils } from '@kit.ArkUI';
603
+
604
+ @Entry
605
+ @ComponentV2
606
+ struct ArrayCompV2 {
607
+ @Local arr: Array<number> = UIUtils.enableV2Compatibility(UIUtils.makeV1Observed([1, 2, 3]));
608
+
609
+ build() {
610
+ Column() {
611
+ Text(`V2 ${this.arr[0]}`).fontSize(20).onClick(() => {
612
+ // 点击触发V2变化,且同步给V1 @ObjectLink
613
+ this.arr[0]++;
614
+ })
615
+ ArrayCompV1({ arr: this.arr })
616
+ }
617
+ .height('100%')
618
+ .width('100%')
619
+ }
620
+ }
621
+
622
+ @Component
623
+ struct ArrayCompV1 {
624
+ @ObjectLink arr: Array<number>;
625
+
626
+ build() {
627
+ Column() {
628
+ Text(`V1 ${this.arr[0]}`).fontSize(20).onClick(() => {
629
+ // 点击触发V1变化,且双向同步回给V2
630
+ this.arr[0]++;
631
+ })
632
+ }
633
+ }
634
+ }
635
+ ```
636
+
637
+
638
+ ### 传递二维数组(V2->V1)
639
+
640
+ 下面的例子中:
641
+
642
+ - 使用makeV1Observed将二维数组的内层数组变成V1的状态变量。调用enableV2Compatibility,使其具有V2的观察能力,也避免V1和V2的双重代理。
643
+ - 在V1中,使用\@ObjectLink接收二维数组的内层数组,因为其为makeV1Observed的返回值,所以点击Button('\@ObjectLink push'),会正常响应刷新。
644
+
645
+ <!-- @[state_mixed_scene_two_bit_array_v2_v1](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneTwoBitArrayV2V1.ets) -->
646
+
647
+ ``` TypeScript
648
+ import { UIUtils } from '@kit.ArkUI';
649
+
650
+ @Component
651
+ struct Item {
652
+ @ObjectLink itemArr: Array<string>;
653
+
654
+ build() {
655
+ Row() {
656
+ ForEach(this.itemArr, (item: string, index: number) => {
657
+ Text(`${index}: ${item}`)
658
+ }, (item: string) => item + Math.random())
659
+ // 新增数组元素
660
+ Button('@ObjectLink push')
661
+ .onClick(() => {
662
+ this.itemArr.push('ObjectLink');
663
+ })
664
+ }
665
+ }
666
+ }
667
+
668
+ @Entry
669
+ @ComponentV2
670
+ struct IndexPage {
671
+ @Local arr: Array<Array<string>> =
672
+ UIUtils.enableV2Compatibility(UIUtils.makeV1Observed([UIUtils.makeV1Observed(['apple']),
673
+ UIUtils.makeV1Observed(['banana']), UIUtils.makeV1Observed(['orange'])]));
674
+
675
+ build() {
676
+ Column() {
677
+ ForEach(this.arr, (itemArr: Array<string>) => {
678
+ Item({ itemArr: itemArr })
679
+ }, (itemArr: Array<string>) => JSON.stringify(itemArr) + Math.random())
680
+ Divider()
681
+ // 数组arr[0]新增元素
682
+ Button('@Local push two-dimensional array item')
683
+ .onClick(() => {
684
+ this.arr[0].push('strawberry');
685
+ })
686
+ // 数组arr新增元素
687
+ Button('@Local push array item')
688
+ .onClick(() => {
689
+ this.arr.push(UIUtils.makeV1Observed(['pear']));
690
+ })
691
+ // 修改数组项arr[0][0]的值
692
+ Button('@Local change two-dimensional array first item')
693
+ .onClick(() => {
694
+ this.arr[0][0] = 'APPLE';
695
+ })
696
+ // 修改数组arr的第一个元素
697
+ Button('@Local change array first item')
698
+ .onClick(() => {
699
+ this.arr[0] = UIUtils.makeV1Observed(['watermelon']);
700
+ })
701
+ }
702
+ }
703
+ }
704
+ ```
705
+
706
+
707
+ ### 传递嵌套类型(V2->V1)
708
+
709
+ 下面例子中:
710
+
711
+ - NestedClassV2中outer调用了UIUtils.enableV2Compatibility,且每一层都是UIUtils.makeV1Observed的返回值,所以outer在V2中有了深度观察的能力。
712
+ - V1中仅能观察第一层的变化,所以需要多层自定义组件,且每层都配合使用\@ObjectLink来接收,从而实现深度观察能力。
713
+
714
+ <!-- @[state_mixed_scene_nested_type_v2_v1](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/ParadigmStateRestock/entry/src/main/ets/pages/mixedStateManageV1V2/StateMixedSceneNestedTypeV2V1.ets) -->
715
+
716
+ ``` TypeScript
717
+ import { UIUtils } from '@kit.ArkUI';
718
+
719
+ class ArrayItem {
720
+ public value: number = 0;
721
+
722
+ constructor(value: number) {
723
+ this.value = value;
724
+ }
725
+ }
726
+
727
+ class Inner {
728
+ public innerValue: string = 'inner';
729
+ public arr: Array<ArrayItem>;
730
+
731
+ constructor(arr: Array<ArrayItem>) {
732
+ this.arr = arr;
733
+ }
734
+ }
735
+
736
+ class Outer {
737
+ @Track public outerValue: string = 'out';
738
+ @Track public inner: Inner;
739
+
740
+ constructor(inner: Inner) {
741
+ this.inner = inner;
742
+ }
743
+ }
744
+
745
+ @Entry
746
+ @ComponentV2
747
+ struct NestedClassV2 {
748
+ // 需保证每一层都是V1的状态变量
749
+ @Local outer: Outer = UIUtils.enableV2Compatibility(
750
+ UIUtils.makeV1Observed(new Outer(
751
+ UIUtils.makeV1Observed(new Inner(UIUtils.makeV1Observed([
752
+ UIUtils.makeV1Observed(new ArrayItem(1)),
753
+ UIUtils.makeV1Observed(new ArrayItem(2))
754
+ ])))
755
+ )));
756
+
757
+ build() {
758
+ Column() {
759
+ Text(`@Local outer.outerValue can update ${this.outer.outerValue}`)
760
+ .fontSize(20)
761
+ .onClick(() => {
762
+ // 可观察第一层的变化
763
+ this.outer.outerValue += '!';
764
+ })
765
+
766
+ Text(`@Local outer.inner.innerValue can update ${this.outer.inner.innerValue}`)
767
+ .fontSize(20)
768
+ .onClick(() => {
769
+ // 可观察第二层的变化
770
+ this.outer.inner.innerValue += '!';
771
+ })
772
+ // 将inner传递给@ObjectLink可观察inner属性的变化
773
+ NestedClassV1ObjectLink({ inner: this.outer.inner })
774
+ }
775
+ .height('100%')
776
+ .width('100%')
777
+ }
778
+ }
779
+
780
+ @Component
781
+ struct NestedClassV1ObjectLink {
782
+ @ObjectLink inner: Inner;
783
+
784
+ build() {
785
+ Column() {
786
+ Text(`@ObjectLink inner.innerValue can update ${this.inner.innerValue}`)
787
+ .fontSize(20)
788
+ .onClick(() => {
789
+ // 可以触发刷新
790
+ this.inner.innerValue += '!';
791
+ })
792
+ NestedClassV1ObjectLinkArray({ arr: this.inner.arr })
793
+ }
794
+ }
795
+ }
796
+
797
+ @Component
798
+ struct NestedClassV1ObjectLinkArray {
799
+ @ObjectLink arr: Array<ArrayItem>;
800
+
801
+ build() {
802
+ Column() {
803
+ ForEach(this.arr, (item: ArrayItem) => {
804
+ NestedClassV1ObjectLinkArrayItem({ item: item })
805
+ }, (item: ArrayItem, index: number) => {
806
+ return item.value.toString() + index.toString();
807
+ })
808
+
809
+ Button('@ObjectLink push').onClick(() => {
810
+ this.arr.push(UIUtils.makeV1Observed(new ArrayItem(20)));
811
+ })
812
+
813
+ Button('@ObjectLink change the last Item').onClick(() => {
814
+ // 在NestedClassV1ObjectLinkArrayItem中可以观察最后一个数组项的属性变化
815
+ this.arr[this.arr.length - 1].value++;
816
+ })
817
+ }
818
+ }
819
+ }
820
+
821
+ @Component
822
+ struct NestedClassV1ObjectLinkArrayItem {
823
+ @ObjectLink item: ArrayItem;
824
+
825
+ build() {
826
+ Text(`@ObjectLink outer.inner.arr item: ${this.item.value}`)
827
+ }
828
+ }
829
+ ```