• Vue3.0 项目中使用事件总线


    vue2.x的项目里,通过 new 一个 Vue 实例的方式,让它来充当事件总线,管理非父子组件之间的事件派发响应。

    1. 先创建一个eventHub.js文件,编辑如下
    import Vue from "vue";
    const eventHub = new Vue();
    export default eventHub;
    
    1. 监听事件的vue组件
    import eventHub from "@/eventHub.js";
    
    export default {
      name: '监听事件的组件',
      created() {
        eventHub.$on("event-name", this.handler);
      },
      methods: {
        handler(params) {
        	console.log('event-name handler', params);
        },
      },
    };
    
    1. 派发事件的vue组件
    import eventHub from "@/eventHub.js";
    
    export default {
      name: '派发事件的组件',
      Mounted() {
        eventHub.$emit("event-name", 'some params');
      },
    };
    

    Vue3.0 中取消 emit 的变动,使得没法再按上面的方式使用了。官方建议使用第三方库mitt

    1. 安装
    npm install --save mitt
    
    1. 注册使用

    创建一个eventHub.js文件

    import Mitt from 'mitt'
    
    const eventHub = new Mitt();
    
    eventHub.$on = eventHub.on;
    eventHub.$off = eventHub.off;
    eventHub.$emit = eventHub.emit;
    
    export default eventHub;
    
    1. 将事件总线注册到 Vue 实例
      main.js
    import {createApp} from 'vue'
    import App from "./App.vue"
    import eventHub from '@/plugins/eventHub.js';
    
    const app = createApp(App);
    
    // 配置全局事件总线
    app.config.globalProperties.eventHub = eventHub;
    
    app.mount('#app');
    
    1. 监听事件的组件
    import { getCurrentInstance, onMounted } from 'vue';
    
    export default {
      name: 'YourComponent',
      setup() {
        const eventHandler = async (params) => {
          // some async process
        };
    
        const { eventHub } = getCurrentInstance().proxy;
        eventHub.$on('event-name', eventHandler);
    
        onBeforeUnmount(() => {
          eventHub.$off('event-name', eventHandler);
        });
      },
    };
    
    1. 派发事件的组件
    import { getCurrentInstance, onMounted } from 'vue';
    
    export default {
      name: '',
      setup() {
        const { eventHub } = getCurrentInstance().proxy;
        
        onMounted(() => {
          eventHub.$emit('event-name', 'some params');
        });
      },
    };
    

    注:

    • 上面封装的时候,使用$emit / $on / $off,是为了方便 Vue2.x的项目做迁移
    • 注意监听要在派发之前,Vue3.0中生命周期的调用顺序要清楚

    动动小手,简单实现一个上面的mitt工具类。

    class EventHub {
      constructor() {
        this.pool = {}
      }
    
      $on(event, handler) {
        this.pool[event] = this.pool[event] || new Set();
    
        this.pool[event].add(handler);
      }
    
      $off(event, handler) {
        this.pool[event].delete(handler);
      }
    
      $emit(event, params) {
        const handlers = this.pool[event];
        if (!handlers || !handlers.size) return;
        handlers.forEach(fn => {
          fn(params);
        })
      }
    
      $clear(event) {
        this.pool[event] = undefined;
      }
    
      $clearAll() {
        this.pool = {};
      }
    
    }
    
    const eventHub = new EventHub();
    
    export default eventHub;
    

    使用方式与上方一致,代码无需改动,效果无异。

    问:如果再要实现一个$once呢?聪明的你来实现一下吧。


    作者:码路工人

    公众号:码路工人有力量(Code-Power)

    欢迎关注个人微信公众号 Coder-Power

    一起学习提高吧~

  • 相关阅读:
    MySql模糊查询like通配符使用详细介绍
    使用powershell批量添加Qt的文件(生成pro)
    宏定义的教训
    使用powershell批量添加Keil和IAR的头文件路径
    python和数据科学(Anaconda)
    CDCE913产生任意频率
    QT中检索设定目录下所有指定文件的方法
    QT中将ASCII转换为对应数值的方法
    STM8如何使用自带的bootloader
    QT中使用函数指针
  • 原文地址:https://www.cnblogs.com/CoderMonkie/p/use-eventhub-in-vue3.html
Copyright © 2020-2023  润新知