Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vue, emitting vs passing function as props

Let's say I have a button component that is imported in several other components. I want the child component to not be coupled to any one type of logic that happens when the button is clicked. So I want to hold that logic in the various components that leverage this button component.

I think there are at least 2 ways of going about this.

  1. Have the child emit an event to the parents, and then let the parents define the handler.

  2. Define the handlers in the parents and pass it down as props to the button component.

I'm used to doing the latter in React. Is there a best practice in vue for this situation?

like image 230
Andrew Kim Avatar asked May 25 '18 15:05

Andrew Kim


People also ask

Can you pass a function as a prop in Vue?

While you can pass a function as a prop, this is almost always a bad idea. Instead, there is probably a feature of Vue that is designed exactly to solve your problem.

How do you pass an object as a prop in Vue?

To pass in the properties of an object as props, we can use the v-bind without the argument. Then the properties of post will be passed into blog-post as prop values. The property names are the prop names.

What does Vue emit do?

Vue $emit is a function that lets us emit, or send, custom events from a child component to its parent. In a standard Vue flow, it is the best way to trigger certain events.


2 Answers

The Vue philosophy is props down, events up. The first option follows that closer as the event itself is emitted (up) to the parent and then handled.

Also within a Vue SFC you have the added benefit of prefixing the bound attribute with a v-on (or @) which describes its intent as an event traveling up and not a v-bind (or :) which implies it's a prop even though its really a callback to an event.

like image 119
Shelton Clinard Avatar answered Oct 09 '22 03:10

Shelton Clinard


Vue.js events are callbacks, they are not DOM events. You can verify this, since you add a custom name to the event listener and not a DOM event name (click, focus...), and there is no event object passed to the function, unless you specify an $event argument in the $emit call.

Events

Pros

  • For libraries: keeps it lighter and clients have more flexibility on methods usage
  • Helpful Vue devtools event logging
  • Allow global listener (this.$root.on), although this can be better enhanced by Vuex.js.
  • Differentiated syntax: : for props and @ for events/methods

Cons

  • Less explicit, harder to debug (fail silently if there are no listeners or the event name is misspelled)

Props

Pros

  • More explicit, are declarative, can be defaulted, required, validated, what turns them easier to debug (runtime errors or compilation errors in TypeScript)

Cons

  • Have to include props validation so you don't have to check if a function() prop exists before calling it (but using props validation is a good practice anyway...)

Conclusion

Looks like the approaches are more convention and personal preference over anything else, although I think that if it wasn't for the Vue.js documentation giving preference to the events approach, everybody would be gladly using props only, which in my opinion is better (clearer).

Props can do everything events do, except for a few cases (like $root event listening pattern - noting Vuex.js replaces this feature and is preferred for scalability), with the advantage they are more explicit, debuggable and check-prone.

Summarized from: https://forum.vuejs.org/t/events-vs-callback-props/11451

like image 37
jpenna Avatar answered Oct 09 '22 02:10

jpenna