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

- Andrés Cruz

En español

Vue.js is one of the great surprises that we have had in recent years by having a framework with which we can build interactive and SPA-type applications without having to use Vue on the entire page, since we can define that we want to use Vue on an entire HTML page or just a fragment of it; It is a fast and easy framework to start and understand and what we are going to see in this article consists of learning a misuse of the use of props whose purpose is to pass data between a parent component to a child component and this data has They have to be primitives like numbers, strings, objects... and not functions. strings, objects... and not functions.

Props allow data to flow unidirectionally, which is essential for maintaining modularity and code reuse.

So, let's start with the following example, where we have a parent component and a child component to which we pass a function:

<template>
 <ChildComponent :callback="toDo" />
</template>
<script>
 export default {
   name: 'ParentComponent',
   methods: {
     toDo() {
       //
     }
   }
 }
</script>

This is incorrect for the following reasons:

The Problem with Passing Functions as Props

Although it is possible to pass functions as props in Vue.js, this can lead to performance issues and difficulties in code maintenance. therefore, we should not employ them; We give some reasons:

  1. References to Functions: When we pass a function as a prop, we are actually passing a reference to that function. This means that if we modify the function in the child component, it will also affect the parent component and any other components that use the same function. This can lead to unexpected side effects and make changes difficult to track.
  2. Difficulty in Maintenance: If we have multiple components that use the same function as a prop, any change to the function will require modifications everywhere it is used. This can become complicated and difficult to maintain as the application grows.
  3. Performance: Passing functions as props can impact performance, especially if the functions are complex or executed frequently. Every time a function is passed as a prop, a new instance of that function is created in the child component. This can cause unnecessary overhead.
<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>

Alternatives and Good Practices

Instead of passing functions as props, we can use custom events, or centralize the functions, for example, putting them in app.vue or using a state manager like Pinia or VueX.

Here we show you the code where we use a custom event called eventInChild and which can have any name, in case you don't know them, all you have to do is define the event in the parent as an attribute in the child, in this example eventInChild:

# ParentComponent
<template>
  <ChildComponent @eventInChild="toDo" />
</template>

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

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

And from the son, wherever we want, we emit it:

# ChildComponent
<script>
  export default {
    methods: {
      eats() {
        this.$emit('eventInChild')
      }
    }
  }
</script>
Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.