Пропсы: defineProps и валидация
Учимся передавать данные в компонент сверху вниз через пропсы: объявляем их через defineProps, задаём типы, обязательность и значения по умолчанию.
Проп (prop) — именованный параметр, который родительский компонент передаёт дочернему, чтобы настроить его поведение или содержимое.
Зачем нужны пропсы
Компонент UserCard бесполезен, если всегда показывает одно и то же. Пропсы делают его настраиваемым: один и тот же компонент рисует разных пользователей в зависимости от переданных данных.
Объявление через defineProps
В <script setup> пропсы объявляют макросом defineProps. В шаблоне они доступны напрямую по имени:
<!-- UserCard.vue -->
<template>
<div class="card">
<h3>{{ name }}</h3>
<p>Возраст: {{ age }}</p>
</div>
</template>
<script setup>
const props = defineProps(['name', 'age'])
</script>
Родитель передаёт пропсы как атрибуты. Статичную строку — обычным атрибутом, динамическое значение — через : (это привязка из раздела 2):
<!-- App.vue -->
<template>
<UserCard name="Аня" :age="25" />
<UserCard :name="user.name" :age="user.age" />
</template>
<script setup>
import { ref } from 'vue'
import UserCard from './components/UserCard.vue'
const user = ref({ name: 'Борис', age: 30 })
</script>
Обратите внимание: :age="25" с двоеточием передаёт число 25, а age="25" без двоеточия передало бы строку "25".
Типы, обязательность, значения по умолчанию
Объектная форма defineProps добавляет проверку типов и значения по умолчанию. Vue предупредит в консоли, если передан не тот тип:
<script setup>
const props = defineProps({
name: { type: String, required: true },
age: { type: Number, default: 0 },
isAdmin: { type: Boolean, default: false },
})
</script>
Поток данных только вниз
Пропсы однонаправленны: данные текут от родителя к ребёнку, но не обратно. Дочерний компонент не должен менять свой проп — это лишь сломает предсказуемость. Если ребёнку нужно сообщить об изменении наверх — он испускает событие (следующий урок). Смоделируем однонаправленный поток:
// Родитель владеет данными
const parentState = { count: 10 };
// Ребёнок получает КОПИЮ значения как проп
function child(propCount) {
// менять локально можно, но на родителя это не влияет
let local = propCount;
local = local + 1;
return local;
}
const result = child(parentState.count);
console.log("Внутри ребёнка:", result);
console.log("У родителя осталось:", parentState.count);
Вывод:
Внутри ребёнка: 11 У родителя осталось: 10
Итог
- Пропсы передают данные от родителя к ребёнку и объявляются через
defineProps. - Объектная форма задаёт
type,requiredиdefaultс проверкой в консоли. :age="25"передаёт число,age="25"— строку.- Поток однонаправленный: ребёнок не меняет проп, а сообщает наверх событием.