网站首页 > 教程文章 正文
组件事件是子组件向父组件传递信息、触发父组件逻辑的重要方式。与 props 的“父传子”方向相反,组件事件实现了“子传父”的通信,是 Vue 组件间交互的核心机制之一。本章将从事件的触发、监听、声明到校验,全面解析组件事件的使用方式。
触发与监听事件
子组件通过触发自定义事件传递信息,父组件则通过监听事件执行相应逻辑,二者配合实现子到父的通信。
子组件触发事件:$emit方法
子组件中可通过 $emit 方法触发自定义事件。$emit 的第一个参数是事件名称(字符串),后续参数为事件传递的数据(可选)。
在模板中,可直接在 v-on(缩写 @)的处理函数中使用 $emit:
<!-- MyComponent 子组件 -->
<!-- 点击按钮时触发 someEvent 事件 -->
<button @click="$emit('someEvent')">Click Me</button>
若需在事件中传递数据,可在 $emit 的第一个参数后添加额外参数:
<!-- 触发事件时附带参数 1 -->
<button @click="$emit('increaseBy', 1)">
Increase by 1
</button>
这里的 1 就是子组件向父组件传递的数据,父组件监听事件时可接收该参数。
父组件监听事件:v-on指令
父组件通过 v-on(缩写 @)监听子组件触发的事件,并绑定处理函数(回调函数)。
基础用法
<!-- 父组件 -->
<!-- 监听子组件的 some-event 事件,触发 callback 函数 -->
<MyComponent @some-event="callback" />
注意事件名称的格式:子组件中若以 camelCase 命名事件(如 someEvent),父组件中可使用 kebab-case(短横线命名,如 some-event)监听——Vue 会自动进行格式转换,与 props 的命名规则一致。推荐在模板中用 kebab-case 编写事件监听器,更符合 HTML 书写习惯。
支持 .once修饰符
组件事件的监听器也支持原生 DOM 事件的 .once 修饰符,仅触发一次后就解绑:
<!-- 仅监听一次 some-event 事件 -->
<MyComponent @some-event.once="callback" />
事件的特性说明
- 无冒泡机制:与原生 DOM 事件不同,组件事件没有冒泡行为。父组件只能监听直接子组件触发的事件,无法监听平级组件或嵌套层级更深的组件的事件。若需跨组件通信,可使用“事件总线”(如通过一个空 Vue 实例传递事件)或全局状态管理方案(如 Pinia)。
- 参数传递:子组件 $emit 时传入的额外参数,会被完整传递给父组件的事件处理函数。例如 $emit('foo', 1, 2, 3) 触发后,父组件的监听器会收到 1、2、3 三个参数。
事件参数的接收与处理
父组件监听事件时,需通过处理函数接收子组件传递的参数,处理方式分为“内联箭头函数”和“组件方法”两种。
内联箭头函数接收参数
若处理逻辑简单,可直接在模板中用内联箭头函数作为监听器,参数会被直接传入函数:
<!-- 父组件:用内联箭头函数接收参数 n,执行 count += n -->
<MyButton @increase-by="(n) => count += n" />
这里的 n 就是子组件 $emit('increaseBy', 1) 传递的参数 1。
组件方法接收参数
若处理逻辑复杂,可将逻辑封装为组件方法,方法会自动接收事件传递的参数:
<!-- 父组件:绑定组件方法 increaseCount 作为监听器 -->
<MyButton @increase-by="increaseCount" />
// 父组件的方法:n 即为子组件传递的参数
function increaseCount(n) {
count.value += n // 例如 n 为 1 时,count 增加 1
}
若子组件传递了多个参数,方法会按顺序接收所有参数。例如子组件 $emit('foo', a, b, c),父组件方法 fooHandler(a, b, c) 会分别收到 a、b、c。
猜你喜欢
- 2025-10-13 Vue el-element ui 清空表格选中记录
- 2025-10-13 Vue3基础难点总结_vue3 从入门到实战 进阶式掌握完整知识体系
- 2025-10-13 分享 15 个 Vue3 全家桶开发的避坑经验
- 2025-10-13 vue 3 学习笔记 (八)——provide 和 inject 用法及原理
- 2025-10-13 vue-element-admin 增删改查(五)_vue element admin 登录修改
- 2025-10-13 微信小程序双向数据绑定,父子传参
- 2025-10-13 Vue3 中有哪些值得深究的知识点?_vue常用知识点
- 2025-10-13 Vue3常用的6种组件通信方式,你一定都用过!
- 2025-10-13 面试官:来说说vue3是怎么处理内置的v-for、v-model等指令?
- 2025-10-13 React 组件复用总踩坑?3 步搞定状态冲突,字节开发都在用的方案
- 最近发表
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)