Reputation: 779
I wrote a functional component that compiles form fields for certain conditions. The form fields are their own component. So I have three levels:
<FormComponent> // handles input events
<FunctionalComponent> // selects form fields
<FormFieldComponent> // emits input events
</FunctionalComponent>
</FormComponent>
Functional components have no this
, but get a context object as argument to the render function. What I could do is using context.data.on[eventName](event)
or some similar construct. I also know that I could use an event bus or the dom elements directly, like described here.
All this looks rather dirty to me.
Is there any this.$emit
equivalent in functional components?
Upvotes: 2
Views: 2663
Reputation: 27789
This is how it looks a functional component emitting an event:
export default {
functional: true,
render(createElement, { listeners }) {
return createElement(
"button",
{
on: {
click: event => {
const emit_event = listeners.event_from_child; //> the name is: event_from_child
emit_event("Hello World!Is this the message we excpected? :/");
}
}
},
"Pass event to parent"
);
}
};
And listening to the parent component:
<functional-component @event_from_child="event_from_child"></functional-component>
See it in action here
Upvotes: 0
Reputation: 779
Thanks to @RoyJ 's comment, I was able to solve my problem. Here for everyone who may face the same problem:
As described in a github issue, the second argument for the render function has a data object that contains all the listeners and more. So the easiest way is to just directly give it to the child component:
render(h, context) {
return h(FormFieldComponent, context.data, children)
}
In my specific case, I only take the listeners directly, because I manipulate large parts of the data object:
render(h, context) {
const data = createDataObject()
data.on = context.data.on
return h(FormFieldComponent, data, children)
}
Upvotes: 1