如果您像我一样在 Vue2 中从任何父/子到任何子/父调用 this.$root.$on(...) 和 this.$root.$emit(...) 上的某些事件,以某种方式保持您的代码更清洁,而不是分别使用一堆发射和道具并拥有您的代码炸了。。
来自 Vue3 文档,事件总线模式可以通过使用实现事件发射器接口的外部库来替换。
使用实现发布-订阅模式的库或编写它。
vue3 event description
现在,如果您使用的是 Option-API(如 vue 2),您需要导入该事件文件,然后在任何组件中正确使用它。
如果您使用的是<script setup>,则需要添加额外的步骤才能让事件库继承代码。
这是一个 pub-sub javascript 模式的基本示例,不要忘记添加 off 方法并在 beforeUnmounted(v3)、beforeDestroy(v2) 上调用它,这样每个挂载的调用就不会执行多个函数)
//event.js
class Event{
constructor(){
this.events = {};
}
on(eventName, fn) {
this.events[eventName] = this.events[eventName] || [];
this.events[eventName].push(fn);
}
emit = (eventName, data)=> (this.events[eventName]) ? this.events[eventName].forEach( fn => fn(data)) : '' ;
}
export default new Event();
如果你正在做 vue2 之类的语法 Option-API:
//在vue组件中
import event from './event';
//mounted or any methods
even.on('GG', data=> console.log(`GG Event received ${data}`))
//显然你必须从另一个组件发出它
//...
import event from './event';
//on mounted or methods click or...
even.emit('GG', {msg:"Vue3 is super Cool"});
如果您使用的是<script setup>,这意味着默认情况下所有变量和方法都会暴露给模板。
//in main.js
import event from './event.js';
//..
app.config.globalProperties.$event = event;
//..
//note if you have an error make sure that you split the the app chaining, like this :
let app = createApp(App);
app.config.globalProperties.$event = event;
app.mount('#app');
//添加一个名为useEvent.js的文件
// useEvent.js
import { getCurrentInstance } from 'vue'
export default useEvent => getCurrentInstance().appContext.app.config.globalProperties.$event;
//在<script setup>中使用它
import useEvent from '@/useEvent'
const event = useEvent();
event.emit('GG');