koehr
koehr

Reputation: 779

How to emit events in a functional Vuejs component

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

Answers (2)

Roland
Roland

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

koehr
koehr

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

Related Questions