Passing functions as props an anti-pattern in Vue.js

Bryan Lee
Bryan Lee
Oct 10, 2019 · 3 min read
Image for post
Image for post
Photo by Nicole De Khors

In React you can pass down functions as props from the parent to the child component. The function call then flows back up from the child to the parent, faciliating parent-child component communication. This is also doable in Vue.js using code like this:

<template>
<Child :callback="doSomething" />
</template>

<script>
export default {
name: 'Parent',

methods: {
doSomething() {
//
}
}
}
</script>

And in the child component, you receive the function as a prop:

<template>
<a @click="execute">Execute action</a>
</template>

<script>
export default {
props: {
callback: {
type: Function
}
},

methods: {
execute() {
// ... do something here

if (this.callback) {
this.callback()
}
}
}
}
</script>

Vue.js custom events as an alternative

While this would work perfectly, this is mostly considered an anti-pattern in Vue. By passing functions down as props, you are linking both parent child components together with two-way data binding. In the example above, the child now needs to know about the context of the function prop from its parent. Every time execute runs, it needs to check for and execute the callback function passed down.

As you reuse this child component, you start having different callback functions passed down from different parents. As the application grows larger in size and other developers come on board, they will look at the child component code and have to figure out which callback function prop it is and where it is from.

Instead, Vue.js has a custom events system that accomplishes the same thing:

# Parent
<template>
<Cat @onHappy="doSomething" />
</template>

<script>
export default {
name: 'Parent',

methods: {
doSomething() {
//
}
}
}
</script>

# Child Cat component
<script>
export default {
methods: {
eats() {
this.$emit('onHappy')
}
}
}
</script>

Whenever the eats method in the Cat component is called, it emits an onHappy event. The parent can then listen for the onHappy event and call a corresponding function. As the data flows in only one way, it makes for much easier debugging too.

The case for passing functions as props

One advantage of passing functions as props is that it makes the code much cleaner and DRYer. Instead of emiting and listening for events, you pass down a function and have it called from the child. While in most cases this is not a good idea, if you have two components that have to be coupled together in any case and the child component does not get reused in other scenarios, this may be a good approach to consider. With that said, events should be the main approach most of the time and this should be used with utmost caution.

This post was first written on my personal blog where you can find more posts related to Javascript and Vue.js. Feel free to also reach out to me directly over LinkedIn or Twitter.

Vue.js Developers

Helping web professionals up their skill and knowledge of…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store