Vue 的事件机制允许组件之间进行通信,通过 $on
、$off
、$emit
和 $once
等方法进行事件的订阅、取消订阅、触发和一次性订阅。我们可以通过手写这些方法来理解其工作原理。
Vue 事件机制
$on(event, callback)
:监听特定事件。$off(event, callback)
:停止监听特定事件。$emit(event, ...args)
:触发特定事件。$once(event, callback)
:只监听一次特定事件。
手写实现
下面是手写这些方法的简单实现:
class EventEmitter {
constructor() {
this.events = {};
}
// 监听事件
$on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
// 停止监听事件
$off(event, callback) {
if (!this.events[event]) return;
if (!callback) {
// 如果没有传递 callback,移除所有事件监听
this.events[event] = [];
} else {
// 移除特定的事件监听
this.events[event] = this.events[event].filter((cb) => cb !== callback);
}
}
// 触发事件
$emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach((callback) => callback.apply(this, args));
}
}
// 只监听一次事件
$once(event, callback) {
const wrapper = (...args) => {
callback.apply(this, args);
this.$off(event, wrapper);
};
this.$on(event, wrapper);
}
}
// 示例
const eventBus = new EventEmitter();
// 监听事件
eventBus.$on("test", (msg) => console.log("test event:", msg));
// 触发事件
eventBus.$emit("test", "Hello, World!");
// 监听一次事件
eventBus.$once("once", (msg) => console.log("once event:", msg));
// 触发一次性事件
eventBus.$emit("once", "This should appear once");
eventBus.$emit("once", "This should not appear");
// 停止监听事件
eventBus.$off("test");
// 触发事件(已经移除监听)
eventBus.$emit("test", "This should not appear");
解释
$on
:将事件和回调函数添加到events
对象中。$off
:如果没有传递回调函数,则移除所有监听。如果传递了回调函数,则只移除特定的回调。$emit
:触发事件,调用所有注册的回调函数并传递参数。$once
:使用一个包装函数 (wrapper
) 包装原始回调函数,确保回调只执行一次,然后移除事件监听。