














本文档基于 HarmonyOS NEXT API 12+ 标准,详细梳理了 @Component(V1)与 @ComponentV2(V2)两套组件体系下的装饰器映射关系、使用差异、代码示例及迁移注意事项,为项目从V1向V2迁移提供权威参考手册。
文档说明
本文档中的V1代指使用 @Component 装饰器的传统组件体系,V2代指使用 @ComponentV2 装饰器的新一代组件体系。所有映射关系均基于官方正式发布的API规范整理。
|
V1 (@Component) |
V2 (@ComponentV2) |
功能说明 |
|
@State |
@Local |
组件内部私有状态,变化时触发UI更新 |
|
@Prop |
@Param |
父组件向子组件单向传递数据 |
|
@Link |
@Param + @Event |
父子组件双向数据同步(V2推荐使用事件回传实现) |
|
@Provide / @Consume |
@Provider() / @Consumer() |
跨层级组件状态传递与共享 |
|
- |
@Event |
子组件向父组件发送事件通知(V2新增) |
|
@Watch |
@Monitor |
监听状态变化并执行回调逻辑 |
|
@Computed |
自动支持 |
派生状态计算,V2无需显式声明,自动缓存结果 |
|
@Observed / @ObjectLink |
自动支持 |
嵌套对象响应式监听,V2无需显式装饰 |
|
@StorageLink / @StorageProp |
@Storage |
本地存储状态绑定,V2统一为@Storage装饰器 |
|
- |
@Effect |
副作用处理,自动跟踪依赖变化(V2新增) |
|
- |
@Memo |
计算结果缓存,避免重复计算(V2新增) |
用于定义组件内部私有的响应式状态,状态变化时触发当前组件UI更新。
|
特性 |
V1 @State |
V2 @Local |
|
作用范围 |
组件内部 |
组件内部 |
|
初始化要求 |
必须初始化 |
必须初始化 |
|
更新粒度 |
组件级 |
节点级(更细粒度) |
|
性能 |
一般 |
更优 |
// V1 实现
@Component
struct Counter {
@State count: number = 0;
build() {
Column() {
Text(`Count: ${this.count}`)
Button("Increment")
.onClick(() => {
this.count += 1;
})
}
}
}
// V2 实现
@ComponentV2
struct CounterV2 {
@Local count: number = 0;
build() {
Column() {
Text(`Count: ${this.count}`)
Button("Increment")
.onClick(() => {
this.count += 1;
})
}
}
}
用于父组件向子组件单向传递数据,父组件数据变化时自动同步到子组件。
|
特性 |
V1 @Prop |
V2 @Param |
|
数据流向 |
父→子单向 |
父→子单向 |
|
默认值支持 |
支持 |
支持(更灵活) |
|
可选参数 |
需要显式声明? |
支持默认值自动可选 |
|
类型校验 |
编译期校验 |
编译期+运行时校验 |
// V1 实现
@Component
struct UserCard {
@Prop name: string;
@Prop age: number = 18; // 可选参数,默认值18
build() {
Column() {
Text(`姓名: ${this.name}`)
Text(`年龄: ${this.age}`)
}
}
}
// 父组件调用
@Component
struct Parent {
build() {
UserCard({ name: "张三" })
}
}
// V2 实现
@ComponentV2
struct UserCardV2 {
@Param name: string;
@Param age: number = 18; // 可选参数,默认值18
build() {
Column() {
Text(`姓名: ${this.name}`)
Text(`年龄: ${this.age}`)
}
}
}
// 父组件调用
@ComponentV2
struct ParentV2 {
build() {
UserCardV2({ name: "张三" })
}
}
V1中通过@Link实现双向绑定,V2中推荐使用单向数据流+事件回传的方式实现,更符合单向数据流设计理念,状态变更更可控。
// V1 @Link 实现
@Component
struct Counter {
@Link count: number;
build() {
Button(`Count: ${this.count}`)
.onClick(() => {
this.count += 1; // 直接修改父组件状态
})
}
}
@Component
struct Parent {
@State count: number = 0;
build() {
Column() {
Text(`父组件Count: ${this.count}`)
Counter({ count: $count }) // 双向绑定
}
}
}
// V2 @Param + @Event 实现
@ComponentV2
struct CounterV2 {
@Param count: number;
@Event onCountChange: (newCount: number) => void; // 事件回调
build() {
Button(`Count: ${this.count}`)
.onClick(() => {
this.onCountChange(this.count + 1); // 通过事件回传新值
})
}
}
@ComponentV2
struct ParentV2 {
@Local count: number = 0;
build() {
Column() {
Text(`父组件Count: ${this.count}`)
CounterV2({
count: this.count,
onCountChange: (newCount) => {
this.count = newCount; // 父组件统一修改状态
}
})
}
}
}
设计理念说明
V2 不再推荐使用双向绑定,而是倡导单向数据流模式,所有状态变更都由持有状态的组件统一处理,状态流向更清晰,更容易追踪和调试。
用于跨多层级组件传递状态,避免逐层传递属性。
// V1 实现
@Component
struct Grandparent {
@Provide theme: string = "light";
build() {
Parent()
}
}
@Component
struct Parent {
build() {
Child()
}
}
@Component
struct Child {
@Consume theme: string;
build() {
Text(`当前主题: ${this.theme}`)
.fontColor(this.theme === "light" ? Color.Black : Color.White)
}
}
// V2 实现
@ComponentV2
struct GrandparentV2 {
@Provider theme: string = "light";
build() {
ParentV2()
}
}
@ComponentV2
struct ParentV2 {
build() {
ChildV2()
}
}
@ComponentV2
struct ChildV2 {
@Consumer theme: string;
build() {
Text(`当前主题: ${this.theme}`)
.fontColor(this.theme === "light" ? Color.Black : Color.White)
}
}
用于监听状态变化,状态变更时执行指定回调逻辑。
// V1 实现
@Component
struct UserProfile {
@State userId: number = 0;
@Watch('userId')
onUserIdChange(newVal: number, oldVal: number) {
console.log(`用户ID从${oldVal}变为${newVal},加载用户信息`);
this.loadUserInfo(newVal);
}
loadUserInfo(userId: number) {
// 加载用户信息逻辑
}
build() {
// UI实现
}
}
// V2 实现
@ComponentV2
struct UserProfileV2 {
@Local userId: number = 0;
@Monitor('userId')
onUserIdChange(newVal: number, oldVal: number) {
console.log(`用户ID从${oldVal}变为${newVal},加载用户信息`);
this.loadUserInfo(newVal);
}
loadUserInfo(userId: number) {
// 加载用户信息逻辑
}
build() {
// UI实现
}
}
V2 新增的 @Effect 装饰器用于处理副作用,自动跟踪依赖变化,无需手动指定监听的状态。
@ComponentV2
struct SearchPage {
@Local keyword: string = "";
@Local page: number = 1;
// keyword或page变化时自动触发,自动跟踪依赖
@Effect
searchData() {
if (this.keyword.length > 0) {
console.log(`搜索关键词: ${this.keyword}, 页码: ${this.page}`);
// 执行搜索逻辑
}
}
build() {
Column() {
Input({ placeholder: "请输入搜索关键词" })
.onChange((value) => {
this.keyword = value;
})
Button("下一页")
.onClick(() => {
this.page += 1;
})
}
}
}
强制注意事项
所有装饰器的替换必须在 @ComponentV2 装饰的组件中使用,@Component 组件不支持V2系列装饰器。
• V1和V2装饰器不能混用在同一个组件中,一个组件要么全部使用V1装饰器,要么全部使用V2装饰器
• V1组件和V2组件可以互相引用,通过标准的属性传递和事件回调通信,完全兼容
• V2装饰器仅支持在API 12及以上版本使用,低版本系统无法运行
1. 优先替换:@State → @Local、@Prop → @Param、@Watch → @Monitor,这三类装饰器替换成本最低,性能提升明显
2. 逐步替换:@Link → @Param + @Event,需要调整数据流向,建议按模块逐步替换
3. 按需使用:@Event、@Effect、@Memo等新增特性,可在新功能开发时逐步引入
• 陷阱1:在V2组件中使用@State装饰器,编译报错。必须替换为@Local。
• 陷阱2:直接修改@Param接收的属性值,V2中@Param是只读的,必须通过@Event回传修改。
• 陷阱3:@Monitor装饰的方法参数顺序错误,V2中参数顺序是(newVal, oldVal),与V1保持一致。
• 陷阱4:忘记移除@Observed装饰器,V2中嵌套对象自动支持响应式,无需额外装饰。
• 陷阱5:在@Effect中修改状态导致死循环,避免在副作用中直接修改依赖的状态。
如果需要同时兼容V1和V2组件,可以使用条件编译实现:
// 条件编译兼容方案
#if (API_VERSION >= 12)
@ComponentV2
#else
@Component
#endif
struct CompatComponent {
#if (API_VERSION >= 12)
@Local count: number = 0;
#else
@State count: number = 0;
#endif
build() {
Button(`Count: ${this.count}`)
.onClick(() => {
this.count += 1;
})
}
}
执行组件从V1向V2迁移时,请对照以下清单逐一检查:
1. ✅ 组件装饰器已从 @Component 替换为 @ComponentV2
2. ✅ 所有 @State 已替换为 @Local
3. ✅ 所有 @Prop 已替换为 @Param
4. ✅ 所有 @Watch 已替换为 @Monitor
5. ✅ 所有 @Provide 已替换为 @Provider
6. ✅ 所有 @Consume 已替换为 @Consumer
7. ✅ 所有 @Link 已重构为 @Param + @Event 模式
8. ✅ 移除了不必要的 @Observed 装饰器
9. ✅ 没有直接修改 @Param 接收的属性值
10. ✅ 验证了所有状态更新逻辑正常工作
11. ✅ 验证了组件生命周期方法正常触发
12. ✅ 进行了性能测试,确认性能提升符合预期
• 新功能优先使用V2:所有新增业务模块优先使用 @ComponentV2 + V2装饰器开发,享受性能提升和新特性
• 增量迁移:存量项目按模块逐步迁移,无需一次性全量替换,降低迁移风险
• 遵循单向数据流:V2中推荐使用单向数据流模式,避免使用双向绑定,提升代码可维护性
• 充分利用新特性:合理使用 @Effect、@Memo 等新特性,简化代码逻辑,提升性能
• 团队规范统一:制定团队统一的V2开发规范,避免不同开发者使用不同的编码风格
长期规划建议
HarmonyOS官方已明确V2是未来的发展方向,V1将进入维护模式。建议所有长期迭代的项目制定迁移计划,在1-2年内完成核心业务模块的V2迁移,以获得更好的性能和特性支持。
文档版本:V1.0 | 适配版本:HarmonyOS NEXT API 12+ | 更新日期:2024年4月
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。