简单实现vue事件机制
Vue 事件机制实现
Vue 的事件机制主要基于发布-订阅模式,可以通过自定义实现一个简化版的事件系统。
核心概念
- 事件中心(Event Hub):管理所有事件的订阅和发布
- $on 方法:订阅事件
- $emit 方法:触发事件
- $off 方法:取消订阅
基础实现代码
class EventEmitter {
constructor() {
this.events = {}
}
$on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = []
}
this.events[eventName].push(callback)
}
$emit(eventName, ...args) {
const callbacks = this.events[eventName]
if (callbacks) {
callbacks.forEach(cb => cb(...args))
}
}
$off(eventName, callback) {
const callbacks = this.events[eventName]
if (callbacks) {
if (callback) {
this.events[eventName] = callbacks.filter(cb => cb !== callback)
} else {
delete this.events[eventName]
}
}
}
}
在 Vue 实例中集成
function initEvents(vm) {
vm._events = Object.create(null)
vm.$on = function(event, fn) {
(vm._events[event] || (vm._events[event] = [])).push(fn)
return vm
}
vm.$once = function(event, fn) {
function on() {
vm.$off(event, on)
fn.apply(vm, arguments)
}
vm.$on(event, on)
return vm
}
vm.$off = function(event, fn) {
if (!arguments.length) {
vm._events = Object.create(null)
return vm
}
const cbs = vm._events[event]
if (!cbs) return vm
if (!fn) {
vm._events[event] = null
return vm
}
vm._events[event] = cbs.filter(cb => cb !== fn)
return vm
}
vm.$emit = function(event) {
const cbs = vm._events[event]
if (cbs) {
const args = Array.prototype.slice.call(arguments, 1)
cbs.forEach(cb => cb.apply(vm, args))
}
return vm
}
}
父子组件通信实现
// 父组件
const parent = new Vue()
parent.$on('child-event', (msg) => {
console.log('收到子组件消息:', msg)
})
// 子组件
const child = new Vue()
child.$emit('child-event', 'Hello from child')
全局事件总线
Vue.prototype.$bus = new Vue()
// 组件A
this.$bus.$on('some-event', (data) => {
console.log(data)
})
// 组件B
this.$bus.$emit('some-event', 'message')
注意事项
- 事件名称最好使用kebab-case命名规范
- 及时在组件销毁时移除事件监听
- 避免滥用全局事件总线,优先考虑props和自定义事件
- 复杂场景考虑使用Vuex状态管理
这种实现方式模拟了Vue核心的事件系统原理,实际Vue源码中事件处理更加复杂,包含更多边界情况处理。







