Join my Vue.js course while it's free 👀

Pass data to components in Vue.js with props

April 3, 2022  ‐ 3 min read

Once you start to split up your Vue application in multiple components, you will at some point want to share variable values from a component to one of its child components. Probably the most straightforward way of passing data to child components in your Vue application is by using component props.

Before you start with props it is good to understand that they have a one-way dataflow, changes are only propagated from parent to childs.

Whenever you try to change the value of a prop in a child component those changes are not applied to the parent component. To reason from the other direction, whenever props change in the parent component, changes to props in a child component are not persisted. So you are better off to treat props as read-only data.

If you do need reactivity there, you can potentially use props to set an initial value for a data property of your child component.

Define props using the options API

In the child component you need to define the props under the props key in your script section.

<script>
  // ChildComponent.vue
  export default {
    props: ["name"],
    computed: {
      welcome() {
        return `Hello ${this.name}`;
      },
    },
  };
</script>

From the parent component you can set the props value of the child component by using attributes. You can either set a hardcoded value or bind a value using :, the shorthand of v-bind.

<template>
  <child-component :name="userName">
  <child-component name="Koen">
</template>

The props are directly available under this in your child component, so in the above example we can access the name using this.name.

Define props using the composition API

Using the composition API which is new in Vue 3 you can pass the props to as the first argument to you setup() function.

<script>
  // ChildComponent.vue
  export default {
    props: ["name"],
    setup(props) {
      // ...
    },
  };
</script>

In case you use a setup script (<script setup>) in single file components you can make use of the defineProps() function to define your component props.

<script setup>
  // ChildComponent.vue
  const props = defineProps(["name"]);
</script>

Typed props

Besides defining props as an array of strings there is an object notation available as well. Which allows to define the property type as well. Your options for the types are String, Number, Boolean, Array, Object and Function. This type is not in any way enforced by Vue, so passing a number while a string is expected will not break your component per-se. However, it will log a friendly warning to the developer console in your browser. Which may helps to spot errors early on.

<script>
  // ChildComponent.vue
  export default {
    props: {
      name: String,
    },
    computed: {
      welcome() {
        return `Hello ${this.name}`;
      },
    },
  };
</script>

Vuex or Pinia Global state

Sharing data with child components is useful. But it can get messy pretty quick as well. Imagine sharing data using props to a child component, which in turn shares it with one of its child components, and that child component shares it with another child component which eventually will be the one that displays that value.

For such a case you are better off using an alternative to component props, that alternative should probably be a global state management library like Vuex or Pinia. Both libraries allow you to share reactive data of your application across all components. Whenever such a global state item changes value, Vue takes care of the re-rendering of components automatically for you.