ArkTS 状态管理 V2 — @Event 装饰器详解

21 阅读4分钟

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 配合使用,实现父子组件之间的状态同步与交互。华为开发者官网