Vue.js 3中使用EventBus报错:Uncaught TypeError: vue__WEBPACK_IMPORTED_MODULE_0__.default is not a constructor
Hey there! Let's sort out this EventBus error you're facing in Vue 3 — I'll break down why it's happening and walk you through simple fixes.
Why the Error Occurs
Your current EventBus.js uses the Vue 2 approach, where you create a new instance of the Vue constructor. But in Vue 3, the default Vue export no longer exists — we initialize apps with createApp instead. That's why new Vue() throws a "not a constructor" error.
Solution 1: Use the mitt Library (Official Recommendation)
Vue 3 doesn't include a built-in EventBus anymore, so the official suggestion is to use a lightweight library like mitt for event communication. Here's how to set it up:
- Install
mittfirst:
npm install mitt # or yarn add mitt
- Update your
EventBus.jsfile:
import mitt from 'mitt' // Create and export the event bus instance export const EventBus = mitt()
- Use it in your components:
- To emit an event (just swap
$emitwithemit):
EventBus.emit('increase-counter')
- To listen for the event (in another component):
import { EventBus } from '../assets/js/EventBus.js' import { onMounted, onUnmounted } from 'vue' export default { setup() { const handleCounterIncrease = () => { // Add your counter logic here console.log('Counter should go up!') } onMounted(() => { // Start listening for the event EventBus.on('increase-counter', handleCounterIncrease) }) onUnmounted(() => { // Clean up the listener when the component unmounts EventBus.off('increase-counter', handleCounterIncrease) }) } }
Solution 2: Create a Custom Event Bus (No External Libraries)
If you don't want to add an extra dependency, build a simple event bus yourself:
Update your EventBus.js to this:
class CustomEventBus { constructor() { this.eventListeners = {} } // Emit an event with optional arguments emit(eventName, ...args) { if (this.eventListeners[eventName]) { this.eventListeners[eventName].forEach(callback => callback(...args)) } } // Listen for an event on(eventName, callback) { if (!this.eventListeners[eventName]) { this.eventListeners[eventName] = [] } this.eventListeners[eventName].push(callback) } // Stop listening to an event off(eventName, callback) { if (this.eventListeners[eventName]) { this.eventListeners[eventName] = this.eventListeners[eventName].filter( listener => listener !== callback ) } } } export const EventBus = new CustomEventBus()
The usage matches the mitt approach — use EventBus.emit(), EventBus.on(), and EventBus.off() in your components.
Quick Side Note
For more complex state management, Vue 3 recommends using Pinia (the official state management library) instead of EventBus. But for simple cross-component event communication, either solution above works great.
内容的提问来源于stack exchange,提问作者Fatemeh motamed

