Props are custom attributes passed from the parent to a child component.
Naming
Long prop names should use camelCase
when declaring, and kebab-case
when passing props to a child component
defineProps({
greetingMessage: String
})
<span>{{ greetingMessage }}</span>
<MyComponent greeting-message="hello" />
Declaring Props
Props need to be registered on a component by declaring it in the list of props a component accepts.
Using <script setup>
it can be done using defineProps
with an array of strings or object syntax
<!-- MyComponent.vue -->
<script setup>
defineProps(['title'])
</script>
<template>
<h4>{{ title }}</h4>
</template>
or the (style guide preferred):
<script setup>
defineProps({
title: String,
likes: Number
})
</script>
In the object declaration syntax, they key is the name of the prop, and the value should be of the expected type.
defineProps
is only available inside <script setup>
, and the declared props are automatically exposed to the template.
Accessing
We can access props in code:
const props = defineProps(['title'])
console.log(props.title)
<template>
<div title=><div/>
<template/>
Passing the data to a registered prop is done through a custom attribute:
<MyComponent title="My journey with Vue" />
<MyComponent title="Blogging with Vue" />
<MyComponent title="Why Vue is so fun" />
You can also render a component for each of the props in an array:
const posts = ref([
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
])
<MyComponent
v-for="post in posts"
:key="post.id"
:title="post.title"
/>
Dynamic Props
Props with static values use strings
<MyComponent title="My journey with Vue" />
But they can also be assigned dynamically with v-bind
/:
shortcut
<!-- Dynamically assign the value of a variable -->
<BlogPost :title="post.title" />
<!-- Dynamically assign the value of a complex expression -->
<BlogPost :title="post.title + ' by ' + post.author.name" />
Doing it this way allows us to use other value types than strings to props. Using the binding causes the prop to be interpreted as a JavaScript expression rather than a string.
This would be a numerical value: 44
<BlogPost :likes="42+2" />
This would be a string: “42+2”
<BlogPost likes="42+2" />
Passing Different Value Types
- Number
<BlogPost :likes="42" />
<!-- Dynamically assign to the value of a variable. -->
<BlogPost :likes="post.likes" />
- Boolean
<!-- Including the prop with no value will imply `true`. -->
<BlogPost is-published />
<!-- this is a JavaScript expression rather than a string. -->
<BlogPost :is-published="false" />
<!-- Dynamically assign to the value of a variable. -->
<BlogPost :is-published="post.isPublished" />
- Array
<BlogPost :comment-ids="[234, 266, 273]" />
<!-- Dynamically assign to the value of a variable. -->
<BlogPost :comment-ids="post.commentIds" />
- Object
<BlogPost
:author="{
name: 'Veronica',
company: 'Veridian Dynamics'
}"
/>
<!-- Dynamically assign to the value of a variable. -->
<BlogPost :author="post.author" />
Binding All Properties of an Object
To pass all object properties as props use v-bind
without an argument
for an object
const post = {
id: 1,
title: 'My Journey with Vue'
}
<BlogPost v-bind="post" />
is equivalent to
<BlogPost :id="post.id" :title="post.title" />
Mutating Props
Props form a one-way-down data binding between the child property and the parent, meaning when the parent property updates, it will update the child, but not the other way around.
Props should not be mutated inside a child component
There are two cases where you might need to mutate a value of a prop:
- The prop is an initial value for a local data property
In this case define the local data property separately and use prop as initial valueconst props = defineProps(['initialCounter']) // counter only uses props.initialCounter as the initial value; // it is disconnected from future prop updates. const counter = ref(props.initialCounter)
- The prop is a raw value that needs to be transformed
In this case define a computed property with the prop’s valueconst props = defineProps(['size']) // computed property that auto-updates when the prop changes const normalizedSize = computed(() => props.size.trim().toLowerCase())
Mutating Object/Array Props
Child components are able to mutate object’s/array’s nested properties due to being passed by reference in js, but this could cause problems with reasoning about data flow.
Children should not mutate object/array props, instead they should emit an event to let the parent perform the mutation