Key*_*yKi 36 javascript vue.js vue-component vuejs3 vue-composition-api
如何在 Vue 3 中创建事件总线?
在 Vue 2 中,它是:
export const bus = new Vue();
Run Code Online (Sandbox Code Playgroud)
bus.$on(...)
bus.$emit(...)
Run Code Online (Sandbox Code Playgroud)
在 Vue 3 中,Vue不再是构造函数,而是Vue.createApp({});返回一个没有$on和$emit方法的对象。
Bou*_*him 72
正如官方文档中所建议的,您可以使用mitt库在组件之间调度事件,假设我们有一个侧边栏,header其中包含一个关闭/打开侧边栏的按钮,我们需要该按钮来切换侧边栏组件内的某些属性:
在 main.js 中导入该库并创建该发射器的实例并定义为全局属性:
安装 :
npm install --save mitt
Run Code Online (Sandbox Code Playgroud)
用法 :
import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt';
const emitter = mitt();
const app = createApp(App);
app.config.globalProperties.emitter = emitter;
app.mount('#app');
Run Code Online (Sandbox Code Playgroud)
在标头中发出toggle-sidebar带有一些有效载荷的事件:
<template>
<header>
<button @click="toggleSidebar"/>toggle</button>
</header>
</template>
<script >
export default {
data() {
return {
sidebarOpen: true
};
},
methods: {
toggleSidebar() {
this.sidebarOpen = !this.sidebarOpen;
this.emitter.emit("toggle-sidebar", this.sidebarOpen);
}
}
};
</script>
Run Code Online (Sandbox Code Playgroud)
在侧边栏中接收带有有效负载的事件:
<template>
<aside class="sidebar" :class="{'sidebar--toggled': !isOpen}">
....
</aside>
</template>
<script>
export default {
name: "sidebar",
data() {
return {
isOpen: true
};
},
mounted() {
this.emitter.on("toggle-sidebar", isOpen => {
this.isOpen = isOpen;
});
}
};
</script>
Run Code Online (Sandbox Code Playgroud)
对于那些使用组合 api 的人,他们可以使用emitter如下:
创建一个文件 src/composables/useEmitter.js
import { getCurrentInstance } from 'vue'
export default function useEmitter() {
const internalInstance = getCurrentInstance();
const emitter = internalInstance.appContext.config.globalProperties.emitter;
return emitter;
}
Run Code Online (Sandbox Code Playgroud)
从那时起,您可以useEmitter像使用以下内容一样使用useRouter:
import useEmitter from '@/composables/useEmitter'
export default {
setup() {
const emitter = useEmitter()
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
小智 21
在 Vue.js 的第 3 版中,您可以使用第三方库,也可以使用以发布者-订阅者(PubSub 概念)编程模式编写的功能。
事件.js
//events - a super-basic Javascript (publish subscribe) pattern
class Event{
constructor(){
this.events = {};
}
on(eventName, fn) {
this.events[eventName] = this.events[eventName] || [];
this.events[eventName].push(fn);
}
off(eventName, fn) {
if (this.events[eventName]) {
for (var i = 0; i < this.events[eventName].length; i++) {
if (this.events[eventName][i] === fn) {
this.events[eventName].splice(i, 1);
break;
}
};
}
}
trigger(eventName, data) {
if (this.events[eventName]) {
this.events[eventName].forEach(function(fn) {
fn(data);
});
}
}
}
export default new Event();
Run Code Online (Sandbox Code Playgroud)
索引.js
import Vue from 'vue';
import $bus from '.../event.js';
const app = Vue.createApp({})
app.config.globalProperties.$bus = $bus;
Run Code Online (Sandbox Code Playgroud)
小智 9
EventBus类文件的内容:
class EventBusEvent extends Event {
public data: any
constructor({type, data} : {type: string, data: any}) {
super(type)
this.data = data
}
}
class EventBus extends EventTarget {
private static _instance: EventBus
public static getInstance() : EventBus {
if (!this._instance) this._instance = new EventBus()
return this._instance
}
public emit(type : string, data?: any) : void {
this.dispatchEvent(new EventBusEvent({type, data}))
}
}
export default EventBus.getInstance()
Run Code Online (Sandbox Code Playgroud)
在项目中的用法,发出事件:
import EventBus from '...path to eventbus file with class'
//...bla bla bla... code...
EventBus.emit('event type', {..some data..}')
Run Code Online (Sandbox Code Playgroud)
监听事件:
import EventBus from '...path to eventbus file with class'
//...bla bla bla... code...
EventBus.addEventListener('event type', (event) => { console.log(event.data) })
Run Code Online (Sandbox Code Playgroud)
我只想在这里提一下,您还可以使用VueUse定义的useEventBus。
下面是 TypeScript 的一个示例,因此使用了注入密钥。
//myInjectionKey.ts
import type { EventBusKey } from '@vueuse/core'
export const myInjectionKey: EventBusKey<string> = Symbol('my-injection-key')
Run Code Online (Sandbox Code Playgroud)
//emmitter
import { useEventBus } from '@vueuse/core'
import { myInjectionKey } from "src/config/myInjectionKey";
const bus = useEventBus(mapInjectionKey)
bus.emit("Hello")
Run Code Online (Sandbox Code Playgroud)
//receiver
import { useEventBus } from '@vueuse/core'
import { myInjectionKey } from "src/config/myInjectionKey";
const bus = useEventBus(myInjectionKey)
bus.on((e) => {
console.log(e) // "Hello"
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18174 次 |
| 最近记录: |