How to add custom events in Vue 3 using TypeScript
Tags: vue, typescript, chatgpt
Published: 2023-03-27 22:57:48


If you're familiar with Vue 3, you already know that it's possible to emit events to notify other components about a change of state or other important information. But what happens when you need to create a custom event that is not part of the standard Vue event list? That's where custom events come in.

In this tutorial, you'll learn how to create custom events in Vue 3 using TypeScript. This tutorial is aimed at beginners who are starting to explore the world of Vue and who already have a beginner knowledge of TypeScript and JavaScript.

## Getting Started

Vue 3 offers an easy way to add custom events to your components. These events can be used to notify other components about the occurrence of an event or to create custom workflows in your Vue application.

To add custom events to a Vue 3 component, we need to define an object to store these events. Let's call this object "eventStack". The "eventStack" is an empty object that will store information about the custom events registered by the component.

To ensure the correct typing of the customizable events, we must create an interface that defines the structure of the events that will be added to the "eventStack" object.

In TypeScript, we can create an interface using the "interface" keyword. In this case, we will create an interface called "EventRegistry" to define the structure of the events that will be registered in the "eventStack" object. The code will look like this:

```typescript
interface EventRegistry {
  [id: string]: (...args: any[]) => void
}
```

To define the "eventStack" object, we can create a constant using TypeScript syntax and assign an empty object to it. The code will look like this:

```typescript
const eventStack: EventRegistry = {}
```

Here, we are declaring a constant called "eventStack" and initializing it with an empty object. We are also providing the type of this object as "EventRegistry", which is the interface we created earlier to define the structure of the custom events.

## Registering and exporting a custom event

To register a custom event, we can create some methods on an object "$evnt", which will be defined as a global object within the Vue scope.

Again, to ensure correct typing, we will create an interface for our object, which will contain the "register", "unregister", and "dispatch" events:

```typescript
interface Evnt {
  register: (eventName: string, callback: Function) => void;
  unregister: (eventName: string, callback: Function) => void;
  dispatch: (eventName: string, ...args: any[]) => void;
}

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $evnt: VueEventMethods;
  }
}
```

Here, we are defining an interface called "VueEventMethods" that has three methods: "register", "unregister", and "dispatch". These methods take in parameters such as the event name and the callback function. The "register" and "unregister" methods will add and remove a new event to the "eventStack" object with the event ID and the callback function provided as an argument. If no callback function is provided, an empty function will be set as the default value. The "dispatch" method will trigger the custom event based on its ID.

We are also using the "declare module" syntax to declare a module that extends the global Vue interface. This allows us to add the "$evnt" object as a global object within the Vue scope. The "$evnt" object will have the type "VueEventMethods", which is the interface we just defined.

After defining the interface and methods for registering and dispatching custom events, we can export them using the global properties of Vue, using the "install" function, similar to what we do with plugins. Here's an example code:

```typescript
export default function install(app: any) {
  app.config.globalProperties.$evnt = {
    register(id: string, callback: (...args: any[]) => void): void {
      eventStack[id] = callback
    },
    unRegister(id: string): void {
      if (eventStack[id])
        delete eventStack[id]
    },
    dispatch(id: string, ...args: any[]): void {
      if (eventStack[id])
        eventStack[id](...args)
    },
  }
}
```

## Using custom events
To use the new events globally, just import them in your "main.ts" file:

```typescript
import events from 'path-to-your-events'

const app = createApp(App)
app.use(event)

// Mount vue app
app.mount('#app')
```

Once you have done this, you can use the events you created in any Vue component in your project:

```typescript
this.$evnt.register('my-event', (data) => {
  console.log('Event registered!', data);
});

// Triggering the custom event
this.$evnt.dispatch('my-event', { message: 'Hello World!' });
```

## Conclusion
In this article, we learned how to add custom events to Vue 3 using TypeScript. We started by defining an object to store our custom events and created an interface to ensure that all events have the same structure.

Next, we learned how to register a custom event with the register function, which allows components to subscribe to specific events. Finally, we saw how to call the custom event when necessary using the dispatch function.

With these tools in hand, you can easily create custom events in your Vue 3 components and make them more flexible and reusable. I hope this article has been helpful and that you can apply these concepts in your future projects!