Writing a general, catch-all event handler in Vue.js

111 Views Asked by At

Vue 3 has a mechanism to emit events from a child component (with $emit) and receive that event in the parent component (with v-on or @). The mechanism is clearly explained here:

https://vuejs.org/guide/components/events.html#emitting-and-listening-to-events

From the documentation, it would seem that for each specific event that the child component emits and that you want to handle in the parent component, you need to define a dedicated v-on handler. That is, you need to know the specific list of events that the child components may emit.

With the composition API, it's easy and elegant to write "wrapping" or decorating parent components that may contain any child components. Such a wrapping component would define a slot for the child component and the top level component would inject a child component as a slot template for the wrapping component.

For instance, one could write a form component that allows displaying multiple inputs of the same kind, or multiple instances of any child component (such as a list of images) and provide add/remove buttons to add or remove instances of this child component. Such a form component would capture all events emitted by the individual child components, pad it with some information such as the index of the component that emitted the event and just emit it further up. Such a component would not, could not and should not know what events are emitted by the child components. It could be any standard event, such as click, input or change, as well as any custom event that the child component might have defined.

Is there any way to define a "catch-all" event handler for all the events emitted by a child component?

Working example:

<!-- MyComponent -->
<button @click="$emit('someEvent', 123)">click me</button>

<MyComponent @some-event="callback" />

// callback() receives 123 as parameter

What I would like:

<!-- MyComponent -->
<button @click="$emit('someEvent', 123)">click me</button>

<MyComponent @dispatch="callback" />

// callback() would receive some $event object as parameter, which contains its type (someEvent) and value (123)
0

There are 0 best solutions below