Как компоненты Vue общаются друг с другом?
JuniorVue.js #vue #components
Вопрос
Какие есть способы передачи данных между компонентами Vue?
Короткий ответ
Базовый принцип — "props вниз, события вверх" (props down, events up): родитель передаёт данные через props, дочерний компонент сообщает об изменениях через emit. Для более сложных случаев есть slots и provide/inject.
Подробный ответ
props— однонаправленный поток данных от родителя к потомку. Дочерний компонент не должен мутировать props напрямую.emit— потомок сообщает о событии родителю (emit('update:modelValue', value)— основаv-model).slots— позволяют родителю передавать разметку внутрь компонента, а не только данные. Именованные и scoped slots дают доступ к данным дочернего компонента из шаблона родителя.provide/inject— передача данных через несколько уровней вложенности без "прокидывания" props через каждый промежуточный компонент (prop drilling). Хорошо подходит для тем оформления, конфигурации, авторизации.- Для несвязанных компонентов — общее состояние (Pinia) или шина событий (используется редко в Vue 3).
Пример
<!-- Parent.vue -->
<script setup>
import { ref } from 'vue'
const title = ref('Привет')
function handleClose() { title.value = '' }
</script>
<template>
<Card :title="title" @close="handleClose">
<template #footer>
<button>Действие</button>
</template>
</Card>
</template>
<!-- Card.vue -->
<script setup>
defineProps<{ title: string }>()
defineEmits<{ close: [] }>()
</script>
<template>
<div>
<h2>{{ title }}</h2>
<slot />
<slot name="footer" />
</div>
</template>
Дополнительные вопросы
- Как реализовать двустороннее связывание через
v-modelв кастомном компоненте? - Чем scoped slot отличается от обычного?
- Когда
provide/injectпредпочтительнее Pinia?