Props are the mechanism for passing data down from a parent component to a child component.
<!-- ChildComponent.vue -->
<script setup>
const props = defineProps({
title: { type: String, required: true },
count: { type: Number, default: 0 },
active: { type: Boolean, default: false },
items: { type: Array, default: () => [] },
user: { type: Object, default: null },
})
</script>
<template>
<div :class="{ active: active }">
<h2>{{ title }} ({{ count }})</h2>
</div>
</template>
<!-- ParentComponent.vue -->
<script setup>
import ChildComponent from './ChildComponent.vue'
const user = { name: 'Alice' }
</script>
<template>
<!-- static prop -->
<ChildComponent title="Hello" />
<!-- dynamic prop (bound) -->
<ChildComponent :title="user.name" :count="42" :active="true" />
<!-- spread an object as props -->
<ChildComponent v-bind="{ title: 'Hi', count: 5 }" />
</template>
Never mutate a prop directly in the child. Instead emit an event to let the parent update the value:
// ❌ Wrong
props.count++
// ✅ Correct — emit to parent
const emit = defineEmits(['update:count'])
emit('update:count', props.count + 1)