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)
})
posted @ 2025-10-02 11:28  wenzhuo4657  阅读(0)  评论(0)    收藏  举报