ArkTS 状态管理 V2 — @Event 装饰器详解
在 HarmonyOS ArkTS 状态管理 V2 组件体系 中,@Event 是用于 定义组件事件输出的装饰器,它让子组件能够通过回调向父组件 触发数据变更或行为通知。常与 @Param 配合使用,实现父子组件之间的交互通信。华为开发者官网
一、为什么需要 @Event
在组件开发中,我们常常需要:
- 子组件向父组件传递用户操作事件;
- 在父组件中处理子组件的状态变更;
- 实现类似 “双向数据绑定” 或 “回调反馈” 的交互逻辑。
虽然 @Param 可以从父组件传递数据到子组件,但它本身 不支持子组件直接修改父组件数据。这就产生了“需要子组件告诉父组件做某件事”的需求。
@Event 的作用正是在这里: 它让子组件声明一个 事件回调接口,父组件可以传入对应函数来响应事件。华为开发者官网
二、核心概念与语法
1. @Event 基本定义
@Event 是 属性装饰器,用于装饰组件内部的 回调函数类型属性,表示该属性是一个事件回调。
语法示例:
@ComponentV2
struct MyButton {
@Event onClick!: () => void;
build() {
Button("点我").onClick(() => {
this.onClick(); // 触发事件回调
});
}
}
上述代码中:
onClick被@Event装饰;- 父组件在使用
<MyButton onClick={...}/>时可以传入回调处理逻辑。华为开发者官网
2. 与 @Param 的配合
为了实现父组件数据的更新,经常会这样组合使用:
- 父组件将数据通过
@Param传入子组件; - 子组件通过
@Event回调通知父组件更新该数据; - 父组件在回调中修改自身状态,从而实现在子组件操作下父组件模型变更的联动。华为开发者官网
示例格式:
<ChildComponent
count={this.count}
onRequestChange={(newCount) => { this.count = newCount }}
/>
在子组件内部:
@Event onRequestChange!: (value: number) => void;
父组件就可以响应用户操作并更新组件状态。
三、详细工作机制
1. 事件作为输出接口传递
@Event 声明的属性不是一个普通字段,而是 子组件对外输出事件的接口声明。这意味着:
- 它用于接收父组件传进来的函数;
- 子组件内部调用该函数代表触发事件;
- 父组件提供具体实现以响应事件。华为开发者官网
2. 子组件调用事件
在组件内部,当某些交互发生时可以调用事件回调:
this.onDeleteItem(item.id);
这与直接修改父组件数据不同,它实际上是 请求父组件进行状态更新。这种模式在 MVVM 或单向数据流架构中非常常见,有利于保证组件内外状态一致性。华为开发者官网
四、常见使用场景
4.1 列表项通知删除
子组件:
@ComponentV2
struct TaskItem {
@Param task!: Task;
@Event onDelete!: (id: string) => void;
build() {
Row() {
Text(this.task.title);
Button("删除").onClick(() => {
this.onDelete(this.task.id);
});
}
}
}
父组件:
<TaskItem
task={item}
onDelete={(id) => { this.tasks = this.tasks.filter(t => t.id !== id); }}
/>
这样的写法清晰表达了: 子组件触发 “删除事件”,由父组件决定如何处理该事件。华为开发者官网
4.2 表单输入回调
用于将子组件的输入值反馈到父组件:
@ComponentV2
struct TextInput {
@Event onChange!: (value: string) => void;
build() {
Input().onChange((e) => {
this.onChange(e.text);
});
}
}
父组件:
<TextInput onChange={(value) => { this.textValue = value; }}/>
五、注意事项与最佳实践
5.1 声明时必须指定类型
事件回调通常包含参数或返回值,建议在声明时明确指定类型:
@Event onSelected!: (id: number) => void;
这样可以提高类型安全性与 IDE 智能提示。华为开发者官网
5.2 不在子组件内部直接修改父组件状态
使用 @Event 的正确方式是:
子组件发起事件请求 → 父组件接收事件并修改自身状态。
不要直接在子组件内部尝试操作父组件数据,否则将违反单向数据流原则。华为开发者官网
5.3 与旧版 @Link 的对比
在 V1 中,可以使用 @Link 做双向绑定,但在 V2 中:
- 统一使用
@Param传参; - 使用
@Event负责向上传递操作; - 组合实现 “双向数据流” 效果。CSDN
六、总结
@Event是 ArkTS V2 中用于 定义组件输出事件的装饰器;- 它允许子组件声明需要传入的回调接口;
- 父组件通过传入回调函数来响应子组件操作;
- 常与
@Param配合使用,实现父子组件之间的状态同步与交互。华为开发者官网