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.