HarmonyOS应用开发实战:猫猫大作战-V1 八装饰器复盘、V1 三大局限、V2 六装饰器预览、迁移决策
2026/7/28 1:59:19 网站建设 项目流程

前言

前面 18 篇(31–48)我们把 V1 状态管理体系用了个遍——@State、@Prop、@Link、@Provide/@Consume、@Observed+@ObjectLink、@Watch、@Reusable、LazyForEach。V1 成熟稳定,但有些本质局限:浅观察要整体赋值、@Observed 类必须 new 实例化、跨组件数据流装饰器多易混、批量更新要靠同调用栈。HarmonyOS 推出了V2 状态管理,用更统一的装饰器和深观察机制解决了这些痛点。

本篇是 V1 收尾总结,对比 V1 与 V2 的核心差异,为下篇 V2 迁移做铺垫。把V1 八装饰器复盘V1 三大局限V2 六装饰器预览迁移决策四大要点讲透。

提示:本系列不讲 ArkTS 基础语法与环境搭建,假设你已跟完第 1–48 篇。本篇是阶段二第十九篇,V1 收尾。

一、V1 八装饰器复盘

1.1 V1 状态管理全家福

装饰器作用核心篇
@State响应式状态,改变触发重渲染第 31
@Prop父子单向只读,浅拷贝第 40
@Link父子双向,$val 传引用第 41
@Provide/@Consume跨层隐式共享,键名匹配第 42
@Observed+@ObjectLink类实例深观察,改内部属性触发第 43
@Watch状态变化副作用回调第 39
@ReusableListItem 复用池,离屏入池第 47

1.2 装饰器关系图

@State(响应式根基) ├─ @Prop(父子单向只读) ├─ @Link(父子双向) ├─ @Provide/@Consume(跨层隐式) ├─ @Observed+@ObjectLink(类实例深观察) └─ @Watch(变化副作用) @Reusable(列表复用,独立)

关键经验V1 以 @State 为根基,其他装饰器要么配合 @State(@Prop/@Link/@Watch/@Observed),要么独立处理列表复用(@Reusable)。

二、V1 三大局限

2.1 局限一:浅观察要整体赋值

@State combo: ComboInfo = { count: 0, multiplier: 1, lastMergeTime: 0 }; @State cats: Cat[] = []; // ❌ 改内部属性不触发 this.combo.count = 5; this.cats[0].y = 7; // ✅ 要整体赋值 this.combo = { ...this.combo, count: 5 }; this.cats = [...this.cats];

痛点:嵌套对象/数组改内部属性要整体赋值,代码冗长且易忘——忘整体赋值就 UI 不刷新,是 V1 最经典 bug。

升级 @Observed 的代价:Cat 要从 interface 改成@Observed class,必须new实例化,子组件必须@ObjectLink——改动面大

2.2 局限二:@Observed 类必须 new 实例化

@Observed export class Cat { constructor(id: string, level: CatLevel, x: number, y: number, falling: boolean) { /* ... */ } } // ✅ 必须 new const cat = new Cat('cat_0', CatLevel.SMALL, 0, 0, true); // ❌ 对象字面量不走构造器,不被 @Observed 标记 const cat = { id: 'cat_0', level: CatLevel.SMALL, x: 0, y: 0, falling: true };

痛点:从 interface 改成 class 要写 constructor,所有实例化点从对象字面量改成 new——迁移成本高

2.3 局限三:跨组件数据流装饰器多易混

场景装饰器传递语法
显示型只读@Propthis.score
编辑型双向@Linkthis.$gameState
跨层隐式@Provide/@Consume键名匹配
类深观察@ObjectLink普通值传
变化副作用@Watch字符串方法名

痛点:五种装饰器语义接近,初学者易混——@Prop 还是 @Link?@ObjectLink 还是 @Prop?@Watch 字符串拼错不报错。

三、V2 六装饰器预览

3.1 V2 状态管理全家福

装饰器作用V1 对应
@Local本地响应式状态@State
@Param父子只读接收@Prop
@Event子触发父回调新(V1 要手写函数 prop)
@Once单次初始化
@ObservedV2+@Trace类实例深观察(字段级)@Observed+@ObjectLink
@Monitor状态变化监听(多字段)@Watch

3.2 V2 的统一简化

// V2:@Local 替代 @State @Local score: number = 0; // V2:@Param 替代 @Prop(且深观察自动) @Param combo: ComboInfo; // 改 combo.count 也触发! // V2:@Event 替代手写函数 prop @Event onScoreAdd: (delta: number) => void; // V2:@ObservedV2 + @Trace 替代 @Observed + @ObjectLink @ObservedV2 export class Cat { @Trace id: string = ''; @Trace x: number = 0; @Trace y: number = 0; // 字段级深观察,改 cat.y 触发 } // V2:@Monitor 替代 @Watch(可监多字段) @Monitor('combo.count, combo.multiplier') onComboChange(monitor: Monitor): void { /* ... */ }

关键经验V2 用更少装饰器覆盖更多场景——@Param 自动深观察省了 @ObjectLink,@Event 替代手写函数 prop 简化跨组件触发。

3.3 V2 深观察的字段级革命

// V1 @Observed:整类深观察 @Observed export class Cat { id: string; // 所有字段都深观察 y: number; } // V2 @ObservedV2+@Trace:字段级深观察 @ObservedV2 export class Cat { id: string = ''; // 不打 @Trace,不深观察 @Trace y: number = 0; // 只 y 深观察 }

关键经验V2 @Trace 字段级深观察——只监听需要响应的字段,省无谓依赖追踪开销。

四、V1 vs V2 核心差异表

4.1 装饰器对照

场景V1V2V2 优势
本地状态@State@Local语义更清晰(本地)
父子只读@Prop(浅拷贝)@Param(深观察)改内部属性也触发
父子双向@Link+$val@Param+@Event分离数据与事件
跨层共享@Provide/@Consume@Provide/@Consume保留(V2 也支持)
类深观察@Observed+@ObjectLink@ObservedV2+@Trace字段级深观察
变化监听@Watch(单字段)@Monitor(多字段)一次监多字段
列表复用@Reusable@Reusable保留

4.2 浅观察 vs 深观察

维度V1 @State/@PropV2 @Local/@Param
嵌套对象改属性❌ 要整体赋值✅ 直接触发
数组项改属性❌ 要两层赋值✅ 直接触发
实例化interface 字面量 OKclass new(V2 也)
代码量多(整体赋值)少(改属性即可)

4.3 批量更新

维度V1V2
被动批量✅ 同调用栈✅ 同调用栈
主动批量❌ 无(要 setTimeout 套路)batchUpdateAPI

4.4 类深观察对比

// V1:整类深观察 + 子必须 @ObjectLink @Observed export class Cat { id: string; y: number; /* 所有字段 */ } @Component struct CatItem { @ObjectLink cat: Cat; // 必须用 @ObjectLink build() { /* ... */ } } // V2:字段级深观察 + 子用 @Param(自深观察) @ObservedV2 export class Cat { id: string = ''; // 不 @Trace,不深观察 @Trace y: number = 0; // 只 y 深观察 } @Component struct CatItem { @Param cat: Cat; // 用 @Param,自深观察 build() { /* ... */ } }

关键经验V2 用 @Param 替代 @ObjectLink——@Param 自带深观察(接 @ObservedV2 实例),不用单独装饰器。

五、迁移决策

5.1 何时迁 V2

场景推荐
新项目✅ 直接上 V2
老项目小改⚠️ 混用 V1 V2(同组件不可混)
老项目大改(状态管理痛点明显)✅ 全迁 V2
老项目稳定无痛点❌ 保持 V1

5.2 混用限制

// ⚠️ 同组件内 V1 V2 不能混 @Component struct BadMixed { @State score: number = 0; // V1 @Local combo: ComboInfo = { /* ... */ }; // V2 // 编译报错或行为未定义 }

关键经验V1 V2 不能在同一组件混用——整个组件要么全 V1 要么全 V2,但不同组件可以分别用 V1 V2。

5.3 迁移工作量评估

迁移项工作量收益
@State → @Local低(改名)语义清晰
@Prop → @Param低(改名)深观察,省整体赋值
@Link → @Param+@Event中(拆双向)数据/事件分离
@Observed → @ObservedV2+@Trace中(字段标 @Trace)字段级深观察
@ObjectLink → @Param低(改名)少一装饰器
@Watch → @Monitor中(改签名)多字段监听

关键经验迁移核心收益是「深观察省整体赋值」和「字段级精细监听」——痛点明显的项目迁 V2 值得。

六、猫猫大作战 V1 现状总结

6.1 当前 V1 用到的装饰器

装饰器用处
@Statescore、cats、combo、gameState 等所有响应式状态31–45
@WatchgameState 变化触发音效/震动39
@Provide/@ConsumegameState、score 跨层共享给嵌套子组件42
@Observed+@ObjectLinkCat 类深观察,CatItem 子组件43、44
@ReusableRecordItem 列表复用(未来战绩页)47

6.2 当前 V1 痛点

痛点当前解法V2 解法
combo 嵌套对象改属性要整体赋值{...this.combo, count: 5}this.combo.count = 5直接触发
cats 数组项改属性要两层赋值引擎返回新数组整体赋值this.cats[0].y = 7直接触发
gameState 变化监听单字段@Watch(‘onGameStateChange’)@Monitor 可监多字段
PauseOverlay 改父 gameState@Link + $val@Param + @Event 分离

关键经验猫猫大作战当前痛点集中在「嵌套对象/数组整体赋值」——迁 V2 能显著简化。

6.3 迁移优先级建议

优先迁: 1. @State → @Local(改名简单,收益语义清晰) 2. @Prop → @Param(改 combo/cats 等嵌套对象为深观察) 3. @Observed → @ObservedV2+@Trace(Cat 字段级深观察) 可选迁: 4. @Link → @Param+@Event(PauseOverlay 等编辑型组件) 5. @Watch → @Monitor(gameState 监听) 保留: 6. @Provide/@Consume(V2 也支持,不改) 7. @Reusable(V2 也支持,不改)

七、踩坑提示

7.1 V1 V2 同组件混用

// ❌ 错误:同组件混用,编译报错 @Component struct Bad { @State score: number = 0; // V1 @Local combo: ComboInfo = { /* ... */ }; // V2 } // ✅ 正确:整个组件统一 V1 或 V2 @Component struct GoodV1 { @State score: number = 0; @State combo: ComboInfo = { /* ... */ }; } @Component struct GoodV2 { @Local score: number = 0; @Local combo: ComboInfo = { /* ... */ }; } `` ### 7.2 以为 V2 全替代 V1 ```ts // ⚠️ V2 不是全替代,有些 V1 装饰器 V2 也支持 @Provide/@Consume // V1 V2 都有,不变 @Reusable // V1 V2 都有,不变

实战经验V2 是 V1 的进化,不是替代——@Provide/@Consume/@Reusable 保持,@State/@Prop/@Link/@Observed/@Watch 升级。

7.3 迁移忘改实例化

// V1 @Observed class @Observed export class Cat { /* ... */ } const cat = new Cat(/* ... */); // V2 @ObservedV2 class @ObservedV2 export class Cat { @Trace y: number = 0; } // 还是 new 实例化,不变 const cat = new Cat(/* ... */); // ⚠️ 但如果 V1 用 interface 对象字面量,迁 V2 要改成 class new `` ## 八、调试技巧 1. **DevEco 版本支持**:确认 DevEco Studio 和 SDK 支持 V2(API 12+)。 2. **`console.info` 对比 V1 V2 行为**:迁后改属性看是否触发(V2 应触发)。 3. **混用排查**:编译报「V1 V2 不能混用」,检查组件内装饰器。 4. **@Trace 忘标**:迁 @ObservedV2 后忘给字段标 @Trace,该字段不深观察。 ## 九、性能与最佳实践 1. **新项目直接上 V2**——深观察省整体赋值,字段级精细监听。 2. **老项目痛点明显才迁**——稳定无痛点保持 V1,迁要全组件迁。 3. **V1 V2 不能同组件混用**——整个组件统一选一版。 4. **@Provide/@Consume/@Reusable V1 V2 都支持**——迁移时这两个保留。 5. **迁移核心收益是深观察**——嵌套对象/数组改属性直接触发,省整体赋值。 6. **@Monitor 多字段监听**——一次监听多个字段变化,比 @Watch 灵活。 ## 十、阶段二进度小结(31–49) 本篇是阶段二「状态管理 + 交互 + 动画」第 19 篇,V1 收尾: | 篇 | 主题 | 核心要点 | |----|------|----------| | 31 | @State | 响应式状态 | | 32 | 多 @State | 同帧批量 | | 33 | setInterval 主循环 | 100ms 物理周期 | | 34 | 计时器 | 1000ms 秒级 | | 35 | spawnTimer | 2000ms 自动生成 | | 36 | clearTimers | -1 哨兵,三时机清理 | | 37 | onClick 列投放 | 闭包捕获 col | | 38 | 箭头函数 this | 回调统一箭头 | | 39 | @Watch | 状态变化副作用 | | 40 | @Prop | 父子单向只读 | | 41 | @Link | 父子双向 $val | | 42 | @Provide/@Consume | 跨层隐式共享 | | 43 | @Observed+@ObjectLink | 类实例深观察 | | 44 | 数组项替换 | ForEach 密钥 diff | | 45 | 批量更新 | 被动批量 + batchUpdate | | 46 | 嵌套陷阱 | 浅观察整体赋值 | | 47 | @Reusable | 列表复用池 | | 48 | LazyForEach | 大列表按需渲染 | | 49(本篇) | V1 局限总结 | V1 V2 差异 | 接下来第 50 篇会专讲 V2 迁移——@Local/@Param/@Event/@Trace/@Monitor 的实战。 ## 总结 本篇我们做 V1 收尾总结,掌握了**V1 八装饰器复盘**、**V1 三大局限(浅观察、@Observed 必须 new、装饰器多易混)**、**V2 六装饰器预览**、**迁移决策(新项目直接 V2,老项目痛点明显才迁)**四大要点。核心要点:**V1 浅观察要整体赋值是最大痛点;V2 @Param 自深观察省整体赋值;@Trace 字段级精细监听;V1 V2 不能同组件混用**。 下一篇我们将专讲 V2 迁移实战——@Local/@Param/@Event/@ObservedV2+@Trace/@Monitor 的改造。 > 如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力! --- **相关资源:** - 「猫猫大作战」项目源码:本仓库 `entry/src/main/ets/pages/Index.ets`、`entry/src/main/ets/components/` - [ArkUI V2 状态管理官方指南](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-state-management-v2) - [ArkUI V1 V2 差异对比官方文档](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-state-management-overview) - [ArkUI 状态管理迁移最佳实践](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/bpta-state-migration) - [开源鸿蒙跨平台社区](https://openharmonycrossplatform.csdn.net) - [HarmonyOS 开发者官方文档首页](https://developer.huawei.com/consumer/cn/doc/) - 系列索引:本仓库 `articles/INDEX.md`

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询