Оголошення через тип - найзручніший спосіб у <script setup lang="ts">:
<script setup lang="ts">
interface Props {
title: string
count?: number
tags?: string[]
}
const props = defineProps<Props>()
</script>
Компілятор сам перетворює тип на runtime-оголошення (title: { type: String, required: true }), тож Vue перевіряє props і під час виконання в режимі розробки.
Значення за замовчуванням - два способи:
1. Деструктуризація props (Vue 3.5+):
const { title, count = 0, tags = () => [] } = defineProps<Props>()
Змінні, отримані деструктуризацією defineProps, лишаються реактивними: компілятор замінює звернення count на props.count. Але є нюанс - передати таку змінну у watch чи composable напряму не можна, лише як геттер:
watch(() => count, (value) => { /* ... */ }) // правильно
watch(count, ...) // помилка компіляції
useSomething(() => count)
2. withDefaults (до 3.5 і досі підтримується):
const props = withDefaults(defineProps<Props>(), {
count: 0,
tags: () => [],
})
Значення-об'єкти й масиви задаються функцією, що повертає нове значення, інакше всі екземпляри компонента ділили б один масив.
Обмеження оголошення через тип:
- тип має бути описаний у файлі чи імпортований з відносного шляху або пакета - компілятор аналізує його статично. Дуже складні умовні типи він не розбере;
- runtime-перевірка бачить лише базові типи (
String,Array), а не вмістstring[]- глибока перевірка лишається за TypeScript.
Не змінювати props усередині компонента. props.title = 'x' - попередження Vue: дані йдуть від батька до дитини, а зміни - назад через події чи defineModel.