Vue2. X uses EventBus for component communication, while mitt.js is recommended for Vue3.

How is mitt. Js better than EventBus on a Vue instance? First, it is small enough to be only 200bytes, second, it supports listening and bulk removal of all events, and it does not rely on Vue instances, so it can be used across frameworks, React or Vue, and even jQuery projects can use the same library.

Quick start

npm install --save mitt
Copy the code

Mode 1, global bus, vue entry file main.js to mount global properties.

import { createApp } from 'vue';
import App from './App.vue';
import mitt from "mitt"

const app = createApp(App)
app.config.globalProperties.$mybus = mitt()
Copy the code

Method 2: Wrap the custom transaction bus file mybus.js, create a new JS file and import it wherever you want to use it.

import mitt from 'mitt'
export default mitt()
Copy the code

Method 3: Import and use components directly. This method is recommended because it is more convenient to manage and troubleshoot problems.

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg=Vue 3.0 + Vite />
</template>

<script>
import mitt from 'mitt'
import HelloWorld from './components/HelloWorld.vue'

export default {
  components: {
    HelloWorld
  },
  setup (props) {
    const formItemMitt = mitt()
    return {
      formItemMitt
    }
  }
}
</script>
Copy the code

use

In fact, the usage of mitt is similar to EventEmitter. On method adds events, off method removes, and clear clears everything.

import mitt from 'mitt'

const emitter = mitt()

// listen to an event
emitter.on('foo'.e= > console.log('foo', e) )

// listen to all events
emitter.on(The '*'.(type, e) = > console.log(type, e) )

// fire an event
emitter.emit('foo', { a: 'b' })

// clearing all events
emitter.all.clear()

// working with handler references:
function onFoo() {}
emitter.on('foo', onFoo)   // listen
emitter.off('foo', onFoo)  // unlisten
Copy the code

It should be noted that mitt is imported in the form of function call, not in the way of new. To remove an event, pass in the function that defines the name and reference of the event.

Core principles

The principle is very simple, is through the map method to save the function. After I cut less than 30 lines of code.

export default function mitt(all) {
	all = all || new Map(a);return {
		all,

		on(type, handler) {
			const handlers = all.get(type);
			const added = handlers && handlers.push(handler);
			if (!added) {
				all.set(type, [handler]);
			}
		},

		off(type, handler) {
			const handlers = all.get(type);
			if (handlers) {
				handlers.splice(handlers.indexOf(handler) >>> 0.1); }},emit(type, evt) {
			((all.get(type) || [])).slice().map((handler) = > { handler(evt); });
			((all.get(The '*') || [])).slice().map((handler) = >{ handler(type, evt); }); }}; }Copy the code

Vue3 completely removes the $on, $OFF, and $once methods from the instance. $EMIT is still part of the existing API because it is used to fire events that are attached declaratively by the parent component.