vue $emit实现原理
Vue $emit 实现原理
Vue 的 $emit 方法用于触发父组件中定义的自定义事件,其核心实现依赖于 Vue 的事件系统和发布-订阅模式。
事件注册与存储
在 Vue 实例初始化过程中,组件会通过 _events 对象存储所有注册的事件监听器。当父组件通过 v-on 或 @ 语法监听子组件的事件时,Vue 会将回调函数注册到子组件的 _events 对象中。
// 示例:父组件监听子组件事件
<child-component @custom-event="handleEvent" />
$emit 方法内部逻辑
$emit 方法的主要逻辑如下:
- 从
_events对象中获取对应事件名的回调函数列表。 - 遍历回调列表,依次执行每个回调函数。
- 支持传递参数,回调函数会接收到这些参数。
Vue.prototype.$emit = function (event) {
const vm = this
let cbs = vm._events[event]
if (cbs) {
const args = Array.prototype.slice.call(arguments, 1)
for (let i = 0; i < cbs.length; i++) {
cbs[i].apply(vm, args)
}
}
return vm
}
事件派发流程
当子组件调用 this.$emit('custom-event', data) 时:
- Vue 查找当前实例的
_events对象中是否存在custom-event的事件监听器。 - 如果存在,则遍历监听器列表,逐个调用回调函数并传入
data参数。 - 父组件的
handleEvent方法会被触发,从而实现父子组件通信。
源码中的关键点
在 Vue 源码中,$emit 的实现还包含以下细节:
- 事件名支持驼峰命名和短横线命名的自动转换。
- 允许通过
$on方法手动注册事件监听器。 - 事件监听器的存储和触发均基于 JavaScript 的原生事件机制,不依赖 DOM 事件系统。
这种设计使得 Vue 的事件系统轻量且高效,适用于组件间的解耦通信。







