vue3入门人话版(五):组件通信和生命周期
在vue中简单入门中,可以通过v-model解决父子组件的通信,但其他组件间的通信该如何解决?有时由于项目过于庞大,想要通信的两个组件之间难以找到桥梁,此时可以通过事件总线,值得提醒的是,在我看来,vuex、react的状态管理也是基于事件总线的高级封装,没错,区别仅仅是事件总线需要开发者完全的自定义。
class SimpleEventBus {
constructor() {
this.listeners = new Map();
}
$on(event, callback) {
if (typeof callback !== 'function') {
console.warn(`[EventBus] listener for "${event}" is not a function.`);
return;
}
if (!this.listeners.has(event)) {
this.listeners.set(event, new Set());
}
this.listeners.get(event).add(callback);
}
$off(event, callback) {
const eventListeners = this.listeners.get(event);
if (!eventListeners) {
return;
}
eventListeners.delete(callback);
if (eventListeners.size === 0) {
this.listeners.delete(event);
}
}
$emit(event, payload) {
const eventListeners = this.listeners.get(event);
if (!eventListeners) {
return;
}
for (const callback of [...eventListeners]) {
try {
callback(payload);
} catch (error) {
console.error(`[EventBus] listener for "${event}" threw an error:`, error);
}
}
}
}
export const EventBus = new SimpleEventBus();
export const Events = Object.freeze({
Button_edit: 'button:edit',
});
以上为ai帮助我编写的一个事件组件,显然,他具备三个基本方法
$on: 用于发布事件
$off: 移除监听
$emit: 用于接收、监听事件。
这个三个方法都是用于维护this.listeners = new Map();这个map类型变量,而他们的使用是基于EventBus这个变量的,如果有一点前端基础就会明白export这个关键字是用于将外部导出,提供访问权限的。
那么此时问题就变成了,在其他组件中如何监听,如何接收?常见做法是在通过声明周期中提供钩子函数进行。
发布
<script setup>
import { EventBus, Events } from '@/envBus/envBus';
let isPreview = true; // true 预览状态 false 编辑状态
function toggleEditorMode() {
isPreview = !isPreview;
EventBus.$emit(Events.Button_edit, isPreview);
}
</script>
<template>
<div>
<button @click="toggleEditorMode">编辑/预览</button>
</div>
</template>
<style>
</style>
监听
// vue组件生命周期:组件挂载完成后执
onMounted(() => {
EventBus.$on(Events.Button_edit, handleEditorToggle)
fetchContent()
})
// vue组件生命周期:在组件实例被卸载之前调用
onBeforeUnmount(() => {
EventBus.$off(Events.Button_edit, handleEditorToggle)
})