When working on a Vue application, you'll need a way to share data between multiple components. Usually, such communication happens between a parent and a child component and props are what makes this process easy. In this topic, you'll learn what props are, how to pass them from a parent component, and how to make them visible in the child component.
What are props?
A prop (short for property) is a way to pass data from a parent component to a child component. Props are custom attributes that you can define on a child component and then pass data to that component and access the data when you need it. There are three main cases when you can use props:
- To pass data from a parent component to a child component;
- To customize components by passing in values for certain properties;
- To increase the reusability of components by allowing them to be used in different contexts with different data.
Imagine you're building a taxi app. Each user in this app can see their past trips that include info about a driver's name, trip cost, and destination. You will need a trip component for each trip, and the number of trips might be thousands, if not more, every day. Instead, what you can do is create one trip component and pass custom data to it. Let's do exactly this!
Our first user Mike has three trips in his history. Let's render the <TripCard /> component three times and pass in different values. That component doesn't exist yet, but no worries — we'll work on it later. Here's a parent component:
<script setup>
import TripCard from './components/TripCard.vue';
</script>
<template>
<div class="container">
<h2>Mike's trips</h2>
<TripCard
driver="Dan"
:cost="250"
from="9 Central Ave"
to="121 Taylor Street"
/>
<TripCard
driver="Max"
:cost="100"
from="98 Lyon Ave"
to="4 Front Street"
/>
<TripCard
driver="Jess"
:cost="170"
from="65 High Meadow Lane"
to="38 Linden Ave"
/>
</div>
</template>
<style>
.container {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
</style>
As you can see, to pass the props to a TripCard you need to name them and assign each of them a custom value. In our case, we have four props: driver, cost, from, to.
Time to flesh out our TripCard component. Create it and make a simple markup like this:
<script setup>
</script>
<template>
<div class="trip-card">
<h3>Trip {{ from }} - {{ to }}</h3>
<p>Driver: {{ driver }}</p>
<p>Cost: {{ cost }}</p>
</div>
</template>
<style>
.trip-card {
border: 1px solid #ccc;
padding: 10px;
text-align: center;
width: 400px
}
</style>
In the template, we tried to access the props by using interpolation, but if you open the app in the browser, you won't see any info that we previously provided. This is because the child component doesn't know about the props yet, so we need to tell it. We'll do that in the next section.
Defining props
There are two main ways to declare the props, either through array or object syntax. You need to use defineProps() macro and either pass in an array with all the prop names, or an object.
- Array syntax:
<script setup>
defineProps(["driver", "cost", "from", "to"]);
</script>
This syntax is useful when you want to specify only the names of the props that are expected without any additional configuration. This syntax is recommended for simple components with only a few props.
- Object syntax:
<script setup>
defineProps({
driver: String,
cost: Number,
from: String,
to: String
});
</script>
The object syntax is used to define more complex props that require additional configuration such as type checking, default values, and validation rules. We'll talk about it in more detail in the next section.
Add any of these syntaxes to your TripCard component, and if you refresh your browser, you should see the info displaying correctly:
If you prefer using a non-setup syntax, you can define props this way:
<script>
export default {
props: {
driver: String,
cost: Number,
from: String,
to: String
}
}
</script>
In this case, you no longer need the defineProps() macro. Instead, use the props option and assign it to an array with prop names or an object, like in the example above.
Prop validation
When we were declaring the props via object syntax, you probably noticed that we specified the type for each prop, String or Number. This is super helpful when you have a lot of data of different types, and you don't want to get confused. You just look at the props object and see exactly what type to expect. It also helps avoid confusion when you work on a team, so each member knows what prop type to work with. Say you mistakenly passed in a string instead of the number, in this case, Vue will notify you:
Vue warn]: Invalid prop: type check failed for prop "cost". Expected Number
with value 250, got String with value "250".
at <TripCard driver="true" cost="250" from="9 Central Ave" ... >
at <App>
There are also other ways to validate props. Let's see some of them you might find useful.
- Multiple types
In case you need to make a prop to be of two or more types, you can specify those types inside an array:
defineProps({
time: [Date, Number]
})
Time can come in Date or Number type, so it's good to account for two possible scenarios.
- Required props
All props are optional by default, but if you want to make some of them mandatory, you can set a required property to true. This way, Vue will warn you if you forget to pass them. Here's how to use the syntax:
defineProps({
name: {
type: String,
required: true
}
})
- Default prop
It's also possible to give your prop a default value so that if you forget to pass it, the default value is used:
defineProps({
name: {
type: String,
default: 'Johny'
}
})Conclusion
Props are a feature in Vue 3 that facilitates the transfer of data from a parent component to a child component. They enable developers to create reusable code that can be customized with different data. We can pass any data type through props (string, boolean, number, etc.) and use it in the child component. It's good practice to stick to kebab-case or camelCase casing. When defining props, it is important to use the appropriate syntax, either array or object, depending on the complexity of the component and the requirements of the props.