Props With defineProps

Receive Data From a Parent

Props With defineProps

defineProps declares typed inputs to a component — at runtime or via TypeScript generics.

5 min read Level 2/5 #vue#props
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())
Custom Events With defineEmits →