Receive Data From a Parent
Props With defineProps
defineProps declares typed inputs to a component — at runtime or via TypeScript generics.
What you'll learn
- Declare props with defineProps
- Add defaults with withDefaults
- Type props with TypeScript
Props are how a parent passes data into a child. In <script setup> you declare them with the defineProps macro — either with a runtime options object or with TypeScript generics.
Runtime Declaration
<script setup>
const props = defineProps({
name: { type: String, required: true },
age: { type: Number, default: 0 },
tags: { type: Array, default: () => [] },
})
</script>
<template>
<p>{{ props.name }} ({{ props.age }})</p>
</template> Validation is enforced in dev mode — passing the wrong type logs a warning.
TypeScript Declaration
Pass an interface as a generic to defineProps. The compiler builds the runtime options for you.
<script setup lang="ts">
interface Props {
name: string
age?: number
tags?: string[]
}
const props = defineProps<Props>()
</script> Defaults With TypeScript — withDefaults
TS prop declarations cannot include defaults directly. Wrap with withDefaults:
<script setup lang="ts">
interface Props {
name: string
age?: number
tags?: string[]
}
const props = withDefaults(defineProps<Props>(), {
age: 0,
tags: () => [],
})
</script> Using Props in the Template
In the template, refer to props by name (no props. prefix needed):
<template>
<p>{{ name }} — age {{ age }}</p>
</template> Read-Only — Do Not Mutate
Props are read-only. If you need a local copy, copy into a ref or compute from the prop.
import { ref, computed } from 'vue'
const localName = ref(props.name)
const upper = computed(() => props.name.toUpperCase())