Випромінювання та користувацькі події у Vue.js
Що таке Emits?
Emits — це спосіб, яким дочірні компоненти спілкуються з батьківськими компонентами у Vue. Дочірній компонент емітить користувацьку подію, а батьківський слухає її. Це протилежно props (батько → дитина).
Основне використання
vue
<!-- ChildComponent.vue -->
<script setup>
const emit = defineEmits(['update', 'delete'])
function handleSave() {
emit('update', { name: 'Alice', age: 25 })
}
function handleDelete() {
emit('delete')
}
</script>
<template>
<button @click="handleSave">Зберегти</button>
<button @click="handleDelete">Видалити</button>
</template>vue
<!-- ParentComponent.vue -->
<template>
<ChildComponent
@update="handleUpdate"
@delete="handleDelete"
/>
</template>
<script setup>
function handleUpdate(data: { name: string; age: number }) {
console.log('Оновлено:', data)
}
function handleDelete() {
console.log('Видалено!')
}
</script>Декларації Emit для TypeScript
vue
<script setup lang="ts">
// Безпечні для типів emits
const emit = defineEmits<{
update: [data: { name: string; age: number }]
delete: [id: string]
search: [query: string, page: number]
close: []
}>()
emit('update', { name: 'Alice', age: 25 }) // ✅ Перевірка типу
emit('update', 'неправильно') // ❌ Помилка типу
emit('close') // ✅ Без навантаження
</script>Валідація Emit
vue
<script setup>
const emit = defineEmits({
// Перевірка значення, що емітиться
update(payload: { name: string }) {
return payload.name.length > 0 // Повертає true, якщо валідно
},
// Без валідації
close: null,
})
</script>v-model з Emits
vue
<!-- CustomInput.vue -->
<script setup>
defineProps<{ modelValue: string }>()
const emit = defineEmits<{ 'update:modelValue': [value: string] }>()
</script>
<template>
<input
:value="modelValue"
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
/>
</template>vue
<!-- Parent.vue -->
<template>
<!-- v-model — це скорочення для :modelValue + @update:modelValue -->
<CustomInput v-model="name" />
</template>Багато v-model
vue
<!-- UserForm.vue -->
<script setup>
defineProps<{ firstName: string; lastName: string }>()
defineEmits<{
'update:firstName': [value: string]
'update:lastName': [value: string]
}>()
</script>
<!-- Parent.vue -->
<UserForm v-model:firstName="first" v-model:lastName="last" />Props вниз, події вгору
Parent
│
├── props ──→ Child (дані течуть ВНИЗ)
│
└── @events ←── Child (події течуть ВГОРУ)Це односторонній потік даних у Vue: батьки передають дані через props, діти сповіщають батьків через emits.
Важливо:
Emits — це стандартний спосіб комунікації від дитини до батька у Vue. Завжди оголошуйте emits за допомогою defineEmits для документації та безпеки типів. Використовуйте узагальнення TypeScript для повністю типізованих подій. Директива v-model є синтаксичним цукром для пари prop + emit (modelValue + update:modelValue).
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.