Как передавать данные в дочерний компонент?

В Vue данные в дочерний компонент передаются с помощью props (свойств) — это механизм, позволяющий родительскому компоненту передать информацию дочернему компоненту, делая компоненты более переиспользуемыми и модульными. Props являются основным способом передачи данных "сверху вниз" (от родителя к дочернему компоненту) во Vue.

Что такое props

Props — это специальные атрибуты, которые задаются на компоненте при его использовании и объявляются внутри компонента-получателя. Vue автоматически делает эти значения доступными в дочернем компоненте, и при их изменении в родителе — происходит реактивное обновление дочернего компонента.

Передача props: пример

Родительский компонент

<template>
<child-component :message="greeting" />
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: { ChildComponent },
data() {
return {
greeting: 'Привет, мир!'
}
}
}
</script>

Дочерний компонент

<template>
<p>{{ message }}</p>
</template>
<script>
export default {
props: \['message'\]
}
</script>

Здесь greeting из родительского компонента передаётся как prop в дочерний компонент и доступен в шаблоне как {{ message }}.

Объявление props

Вариант 1 — массив строк:

props: \['title', 'count'\]

Вариант 2 — объект с типами, значениями по умолчанию и валидацией:

props: {
title: {
type: String,
required: true
},
count: {
type: Number,
default: 0
},
isVisible: {
type: Boolean,
default: true
}
}

Односторонняя привязка

Props во Vue работают по односторонней (однонаправленной) привязке: данные передаются от родителя к дочернему компоненту, но не наоборот. Это означает:

  • Если родитель обновит значение пропа — дочерний компонент отреагирует.

  • Если дочерний компонент попытается изменить значение пропа напрямую — Vue выдаст предупреждение.

Изменение props внутри дочернего компонента

Нельзя мутировать проп прямо в дочернем компоненте — это нарушает принцип одностороннего потока данных. Если нужно его изменить, можно:

  1. Создать копию пропа в data:
props: \['initialCount'\],
data() {
return {
localCount: this.initialCount
}
}
  1. Использовать v-model и эмитить update:modelValue (подробнее ниже).

Использование динамических props

Можно передавать вычисляемые значения:

<user-card :name="user.name" :age="user.age + 1" :active="user.isOnline" />

Можно даже передать объект:

<user-card :user="userObject" />

А в компоненте:

props: {
user: Object
}

Использование props в шаблоне и скрипте

Props доступны:

  • В шаблоне: {{ propName }}

  • В скрипте: this.propName

Пример:

<template>
<h1>{{ title }}</h1>
</template>
<script>
export default {
props: \['title'\],
mounted() {
console.log('Заголовок:', this.title)
}
}
</script>

Передача нескольких props

<product-card :name="product.name" :price="product.price" :stock="product.stock" />

И в компоненте:

props: {
name: String,
price: Number,
stock: Number
}

CamelCase и kebab-case

При передаче props через шаблон HTML используется kebab-case:

<user-profile :user-name="name" />

В JavaScript/JSX — camelCase:

props: \['userName'\]

Vue автоматически сопоставляет user-name с userName.

Использование с v-bind

Можно использовать v-bind без аргументов для передачи всех свойств объекта как props:

<user-profile v-bind="userData" />

Если userData = { name: 'Alex', age: 30 }, то это эквивалентно:

<user-profile :name="userData.name" :age="userData.age" />

Prop как функция обратного вызова (callback)

Можно передать функцию:

Родитель:

<child-component :onSubmit="handleSubmit" />

Дочерний:

props: \['onSubmit'\],
methods: {
doSubmit() {
this.onSubmit('данные из формы');
}
}

v-model и props

Если компонент должен поддерживать v-model, он должен:

  • Принимать modelValue как проп.

  • Эмитить событие update:modelValue.

Пример:

<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>
<script>
export default {
props: \['modelValue'\]
}
</script>

Родитель:

<custom-input v-model="userInput" />

Проверка типов и валидация props

Vue позволяет валидировать передаваемые props по типу, обязательности и даже кастомной функции:

props: {
age: {
type: Number,
required: true,
validator: function (value) {
return value >= 0 && value <= 150
}
}
}

Если значение не проходит проверку — Vue выводит предупреждение в консоли.

Реактивность и отслеживание изменений props

Props являются реактивными. Это означает:

  • При изменении данных в родителе — дочерний компонент автоматически обновится.

  • Можно использовать watch в дочернем компоненте, чтобы реагировать на изменения пропов:

props: \['status'\],
watch: {
status(newVal, oldVal) {
console.log('Статус изменился с', oldVal, 'на', newVal);
}
}

Общий паттерн передачи данных

Рекомендуемый паттерн во Vue:

  1. Родитель передаёт данные через props.

  2. Дочерний компонент работает с ними только для отображения или генерации событий.

  3. Если дочернему компоненту нужно изменить данные — он генерирует событие emit.

  4. Родитель обрабатывает событие и изменяет данные, передаваемые вниз.