带有 Composition API 的 Vue 3 事件总线

问题描述 投票:0回答:4

我已经设置了 mitt 并尝试将事件分派到另一个组件,但我遇到了困难,因为在

setup()
方法中它没有
this
用于访问应用程序实例。

这是我尝试过的:

import App from './App.vue'
const el = document.getElementById('app')

import mitt from 'mitt';
const emitter = mitt();

const app = createApp(App)
app.config.globalProperties.emitter = emitter;
app.mount(el);

在组件中,我想调度一个事件

export default {
   setup() {
      function toggleSidebar() {
          this.emitter.emit('toggle-sidebar');

          console.log(this); // binds to setup(), not the vue instance.
      }
   }
}

由于

this
不存在,我无法访问
.emitter
。我缺少什么?如何在 Vue 3 组合 api 中使用官方建议的手套?


顺便说一句,如果我使用 v2 语法,我可以访问

this.emitter
。但我对 Composition API 方式很好奇

export default {
  mounted() {
    console.log(this.emitter); // works
  }
} 
javascript vue.js vuejs3 event-bus vue-composition-api
4个回答
31
投票

要在 Vue 3 Composition API 中使用事件总线,请在 main.js

 中使用 Vue 3 的新 
provide api,然后在任何组件中使用
inject

1。安装手套

npm install mitt

2。提供:

main.js

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

import mitt from 'mitt';                  // Import mitt
const emitter = mitt();                   // Initialize mitt

const app = createApp(App);
app.provide('emitter', emitter);          // ✅ Provide as `emitter`
app.mount('#app');

3.注入

3a。 任何组件 - 发出事件

import { inject } from 'vue'

export default {
  setup() {
    const emitter = inject('emitter'); // Inject `emitter`
    const mymethod = () => {
      emitter.emit('myevent', 100);
    };
    return {
      mymethod
    }
  }
}

通过单击按钮或其他方式呼叫

mymethod

3b。 任何组件 - 监听事件

import { inject } from 'vue'

export default {
  setup() {
    const emitter = inject('emitter');   // Inject `emitter`

    emitter.on('myevent', (value) => {   // *Listen* for event
      console.log('myevent received!', `value: ${value}`);
    });
  },
}

控制台

myevent received! value: 100 

2
投票

您可以使用

getCurrentInstance
来获取全局属性

组件:

import { getCurrentInstance } from 'vue';
export default {
  setup() {
    // get current instance
    const internalInstance = getCurrentInstance(); 
    // get the emitter from the instance
    const emitter = internalInstance.appContext.config.globalProperties.emitter;
  }
} 

2
投票

到目前为止,我已经使用此代码来使“发射器”可用。

//main.ts
import mitt from 'mitt'
const emitter = mitt()
export default emitter

然后在我使用的组件内部

import emitter from '@/main';

到目前为止,这在 Vue2 和 Vue3 中有效 - 至少在选项 API 中有效。

我必须承认,我目前在新的 vite 服务器和热模块重新加载(hmr)方面遇到了一些麻烦。 这种风格是否不是最理想的?


0
投票

这个方法对我很有帮助。但是第一次听到 1 信息和第二次听到 2 信息即将到来,如何解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.