How to emit an event from Vue.js Functional component?
If you want to pass event listener conditionally you can do it inside functional component template like this:
v-on="listeners.change ? { change: listeners.change } : null"
The issue of conditionally attaching listeners is discussed here
This is explained in the docs Passing Attributes and Events to Child Elements/Components:
If you are using template-based functional components, you will also have to manually add attributes and listeners. Since we have access to the individual context contents, we can use
data.attrs
to pass along any HTML attributes andlisteners
(the alias fordata.on
) to pass along any event listeners.
At the most basic level, you can delegate all listeners like this:
<some-child v-on="listeners"></some-child>
If you only want to bind the change
listener, you can do:
<some-child @change="listeners.change"></some-child>
but this will fail if listeners.change
is undefined/null (not provided to the functional component).
If you need to handle the situation where there is no change
listener, then you can do this:
<some-child @change="listeners.change && listeners.change($event)"></some-child>
otherwise you would have to settle by writing the render function by hand, since I don't think it is possible to conditionally assign the change
listener to <some-child>
in the template of a functional component. (Or maybe you can? I'm not sure.)
Child Component
<template functional>
<button @click="listeners['custom-event']('message from child')">
Button from child
</button>
</template>
Parent Component
<template>
<div>
<child-component @custom-event="call_a_method" />
</div>
</template>
See it in action on codesandbox
Do you want to emit the event from the vue instance?
export default {
functional: true,
render(createElement, { listeners }) {
return createElement(
"button",
{
on: {
click: event => {
const emit_event = listeners.event_from_child;
emit_event("Hello World!Is this the message we excpected? :/");
}
}
},
"Pass event to parent"
);
}
};
See it also a sandbox example here