How to use props to pass data to child components in Vue 3 - LogRocket Blog (2024)

Editor’s note: This article was last updated on 26 December 2023 to cover how to work with multiple props in Vue and how to set default values for props.

How to use props to pass data to child components in Vue 3 - LogRocket Blog (1)

Props are an important feature in Vue for managing parent and child components, but handling them can be somewhat tricky. In this article, we’ll learn how to pass data from a parent component to child components by using props in Vue 3. You can find the complete code for this tutorial on GitHub. Let’s get started!

Prerequisites

This article is suited for developers of all stages, including beginners. To follow along, you’ll need Node.js version ≥16.x installed. You can verify if you already have it installed by running the command node -v in your terminal or the command prompt.

You’ll also need a code editor; I highly recommend VS Code.

Finally, you’ll need Vue 3 installed globally on your machine. At the time of writing, Vue 3 is the latest version.

Before getting started, download a Vue starter project. Unzip the downloaded project, navigate into the unzipped file, and then run the command below to keep all the dependencies up to date:

npm install

What are props in Vue?

In Vue, props are custom attributes that you can register on any component. You define your data on the parent component and give it a value. Then, you go to the child component that needs that data and pass the value to a prop attribute. Therefore, the data becomes a property in the child component.

In a <script setup> component, the syntax looks like the following code:

<script setup>const props = defineProps(['title'])console.log(props.title)</script>

In a non-<script setup> component, the syntax looks like this:

export default { props: ['title'], setup(props) { // setup() receives props as the first argument. console.log(props.title) }}

To access this data dynamically from any component that needs it, you can use the root component App.vue as the parent component, store the data, and then register props.

Vue.js prop types

Vue uses a more flexible approach to props where you can specify the type of a prop using JavaScript constructors:

export default { props: { propA: { type: String, } }}

The types could be String, Number, Boolean, Array, or Object.

The String type accepts only string values, the prop with Number type accepts only numeric values, the prop with Boolean type accepts only Boolean values, and the prop with Array or Object type accepts only array or object values respectively.

Why should you use props in Vue?

Let’s say you have an array of objects that you want to display in two different components. For example, component A renders the artist names from the array of objects while component B renders the artist names and countries from the array of objects. Your first instinct might be to create these two separate components, add the array inside the data object, and then display them in the template.

This solution is great initially, but as you add more components, it becomes complicated. Let’s demonstrate this with the starter project you’ve opened in VS Code. Open the Test.vue file and copy the code block below:

<template> <div> <h1>Vue Top 20 Artists</h1> <ul> <li v-for="(artist, x) in artists" :key="x"> <h3>{{artist.name}}</h3> </li> </ul> </div></template><script>export default { name: 'Test', data (){ return { artists: [ {name: 'Davido', genre: 'afrobeats', country: 'Nigeria'}, {name: 'Burna Boy', genre: 'afrobeats', country: 'Nigeria'}, {name: 'AKA', genre: 'hiphop', country: 'South-Africa'}, {name: 'Sarkodie', genre: 'hiphop', country: 'Ghana'}, {name: 'Stormzy', genre: 'hiphop', country: 'United Kingdom'}, {name: 'Lil Nas', genre: 'Country', country: 'United States'}, {name: 'Nasty C', genre: 'hiphop', country: 'South-Africa'}, {name: 'Shatta-walle', genre: 'Reagae', country: 'Ghana'}, {name: 'Khalid', genre: 'pop', country: 'United States'}, {name: 'ed-Sheeran', genre: 'pop', country: 'United Kingdom'} ] } }}</script>

Create a new file in the components folder called Test2.vue and paste the following code block inside it:

<template> <div> <h1>Vue Top Artist Countries</h1> <ul> <li v-for="(artist, x) in artists" :key="x"> <h3>{{artist.name}} from {{artist.country}}</h3> </li> </ul> </div></template><script>export default { name: 'Test2', data (){ return { artists: [ {name: 'Davido', genre: 'afrobeats', country: 'Nigeria'}, {name: 'Burna Boy', genre: 'afrobeats', country: 'Nigeria'}, {name: 'AKA', genre: 'hiphop', country: 'South-Africa'}, {name: 'Sarkodie', genre: 'hiphop', country: 'Ghana'}, {name: 'Stormzy', genre: 'hiphop', country: 'United Kingdom'}, {name: 'Lil Nas', genre: 'Country', country: 'United States'}, {name: 'Nasty C', genre: 'hiphop', country: 'South-Africa'}, {name: 'Shatta-walle', genre: 'Reagae', country: 'Ghana'}, {name: 'Khalid', genre: 'pop', country: 'United States'}, {name: 'ed-Sheeran', genre: 'pop', country: 'United Kingdom'} ] } }}</script><style scoped>li{ height: 40px; width: 100%; padding: 15px; border: 1px solid saddlebrown; display: flex; justify-content: center; align-items: center; } a { color: #42b983;}</style>

To register the new component you just created, open the App.vue file and copy the code below inside it:

<template> &lt;div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <Test/> <Test2/> </div></template><script>import Test from './components/Test.vue'import Test2 from './components/Test2.vue'export default { name: 'app', components: { Test, Test2 }}</script>

In the VS Code terminal, serve up the application in the development environment with the following command:

npm run dev

It should look like the following:

How to use props to pass data to child components in Vue 3 - LogRocket Blog (2)

You’ll notice that if you had only about five more components, you would have to keep copying the data in every component. Imagine there was a way that you could define the data in a parent component and then bring it into every child component that needs it by using the property name. This is where using props to pass data from parent to child components comes in handy.

Defining data in the parent component

Because you’ve chosen the root component to be your parent component, you first have to define the data object that you want to share dynamically inside of the root component.

If you’ve followed this article from the start, open up your App.vue file and copy the data object code block inside of the script section:

<template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png" /> <Test /> <Test2 /> </div></template><script>import Test from "./components/Test.vue";import Test2 from "./components/Test2.vue";export default { name: "app", components: { Test, Test2, }, data() { return { artists: [ { name: "Davido", genre: "afrobeats", country: "Nigeria" }, { name: "Burna Boy", genre: "afrobeats", country: "Nigeria" }, { name: "AKA", genre: "hiphop", country: "South-Africa" }, { name: "Sarkodie", genre: "hiphop", country: "Ghana" }, { name: "Stormzy", genre: "hiphop", country: "United Kingdom" }, { name: "Lil Nas", genre: "Country", country: "United States" }, { name: "Nasty C", genre: "hiphop", country: "South-Africa" }, { name: "Shatta-walle", genre: "Reagae", country: "Ghana" }, { name: "Khalid", genre: "pop", country: "United States" }, { name: "Ed Sheeran", genre: "pop", country: "United Kingdom" }, ], }; },};</script>

Receiving props in Vue

After defining the data, go into the two test components and delete the data objects inside them.

To receive props in a component, you have to specify the props that you want to receive inside of that component. Go inside the two test components and add the specifications in the script section, as shown below:

<script>export default { name: 'Test', props: ['artists']} </script> 

Registering props in Vue

To let the Vue engine know that you have props you want to dynamically pass to some child components, you have to indicate this in the Vue instance. This is done in the template section as shown here:

<template> <div id="app"> <Test v-bind:artists="artists"/> <Test2 v-bind:artists="artists" /> </div></template>

In the code above, we use the v-bind directive to bind artists, which is the name of the data object array in the script section, and artists, the prop name in the test components, which you set up in the section above.

If you set it up without the following directive, you won’t see any output; neither the Vue compiler nor ESLint will flag it as an error or warning:

 <Test artists="artists"/> <Test2 artists="artists"/>

Therefore, it’s important to pay attention and remember to use v-bind for every dynamic binding.

Over 200k developers use LogRocket to create better digital experiencesLearn more →

Using props in Vue

After you’ve set up the props in your Vue app, you can then use them inside of your component as if the data were defined inside of the same component. Therefore, in our demo case, you can set up method calls and easily access this.artists.

Strongly typing props

By strongly typing the props, you can also ensure that your component only receives exactly the data type you want it to. In our demo, for instance, you can ensure that only arrays get passed down to your component by setting up authentication as follows:

<script>export default { name: 'Test', props: { artists: { type: Array } }}</script>

Therefore, whenever you add a wrong type, say, a String, you’ll get a warning in the console telling you that the type it received is not the type it expected:

How to use props to pass data to child components in Vue 3 - LogRocket Blog (5)

How to set default values for props

You can set default values for props using the default property in the props option:

<script>export default { props: { propWithDefaultString: { type: String, default: 'Default String', }, }}

The default value of a prop should correspond with the specified type.

How to work with multiple props

Working with multiple props is similar to working with a single prop, but you need to declare and define each prop in the component’s props option.

Registering multiple props

Using the component in a parent component, you can pass values for each prop as follows:

<template> <div> <ChildComponent prop1="Hello" :prop2="100" :prop3="true" /> </div></template><script>import ChildComponent from './ChildComponent.vue';export default { name: "ParentComponent", components: { ChildComponent, },}</script>

Receiving multiple props in the child component

In the child component definition, declare the props option as an object where each property represents a prop. You can specify the type, default value, and other options for each prop:

<script>export default { props: { prop1: { type: String, required: true, }, prop2: { type: Number, default: 42, }, prop3: { type: Boolean, default: false, } }}</script>

In the above code, prop1 is a required prop of type String, prop2 is an optional prop of type Number with a default value of 42, while prop3 is an optional prop of type Boolean with a default value of false.

You can use the props in the child component’s methods or computed properties just like any other data property:

<script>export default { props: { ... }, methods: { combineProps() { return `${this.prop1} - ${this.prop2} - ${this.prop3 ? 'True' : 'False'}`; }, },}</script>

In the child component’s template, you can access the props using the {{ }} syntax:

<template> <div> <p>Prop 1: {{ prop1 }}</p> <p>Prop 2: {{ prop2 }}</p> <p>Prop 3: {{ prop3 }}</p> </div></template>

Working with multiple props in the Vue 3 Composition API

In the Vue 3 Composition API, working with multiple props is slightly different than in the Options API discussed above.

In the Composition API, you can use the defineProps function to declare and define props:

<script>export default { props: { prop1: { type: String, required: true, }, prop2: { type: Number, default: 42, }, prop3: { type: Boolean, default: false, }, }, setup(props) { console.log(props.prop1, props.prop2, props.prop3); return { props }; },};</script>

The first argument in the setup function is the props argument. You can use the prop values directly in the template as follows:

<template> <div> <p>Prop 1: {{ props.prop1 }}</p> <p>Prop 2: {{ props.prop2 }}</p> <p>Prop 3: {{ props.prop3 }}</p> </div></template>

You may want to destructure the props object in the setup function; by doing this, the destructured variables will lose reactivity. It is therefore recommended to always access props in the form of props.xxx.

But if you need to destructure the props, or need to pass a prop into an external function while retaining reactivity; you can do so with the toRefs() and toRef() utility APIs:

<script>import { toRefs } from 'vue'export default { props: { ... } setup(props) { const { prop1 } = toRefs(props) console.log(prop1.value) return { prop1 } }}</script>

Here, we use toRefs to turn the props into an object of refs to destructure. prop1 is a ref that tracks props.prop1.

You can use the destructured prop values directly in the template as follows:

<template> <div> <p>Prop 1: {{ prop1 }}</p> </div></template>

How to pass functions to props

In Vue 3, you can pass functions as props to child components in a similar way to passing
any other data.

In the parent component, define a function that you want to pass as a prop:

 <template> <div> <ChildComponent :customFunction="functionA" /> </div></template><script>import ChildComponent from './ChildComponent.vue';export default { name: "ParentComponent", components: { ChildComponent, }, methods: { functionA() { console.log('Function from the parent component'); }, },};</script>

In the child component, declare the prop to accept a function. You can do this by adding a props option and specifying the type as Function:

<script>import { PropType } from 'vue';export default { props: { customFunction: { type: Function as PropType<() => void>, required: true, }, }, methods: { executeFunction() { this.customFunction(); }, },};</script>

You can then use it in the child component template as follows:

<template> <div> <button @click="executeFunction">Call Parent Function</button> </div></template>

Conclusion

In this article, we explored props in Vue 3, learning how they can help to encourage the DRY (don’t repeat yourself) approach by creating a platform for reusing data objects. For additional information, check out Vue’s official documentation on props.

Happy coding!

Experience your Vue apps exactly how a user does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket.

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens in your Vue apps, including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps — start monitoring for free.

How to use props to pass data to child components in Vue 3 - LogRocket Blog (2024)
Top Articles
Latest Posts
Article information

Author: Lilliana Bartoletti

Last Updated:

Views: 6310

Rating: 4.2 / 5 (53 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Lilliana Bartoletti

Birthday: 1999-11-18

Address: 58866 Tricia Spurs, North Melvinberg, HI 91346-3774

Phone: +50616620367928

Job: Real-Estate Liaison

Hobby: Graffiti, Astronomy, Handball, Magic, Origami, Fashion, Foreign language learning

Introduction: My name is Lilliana Bartoletti, I am a adventurous, pleasant, shiny, beautiful, handsome, zealous, tasty person who loves writing and wants to share my knowledge and understanding with you.