vue, emitting vs passing function as props
As a newbie perspective migrated from React, I don't know why @event
even exists (or like the answers above - being the standard). I can't declare which events
a component would $emit
?, but I can easily see which props
are passed down. And by a good naming, I will be able to know which one is actually a callback event.
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 noevent
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
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.