Компонент повідомляє батька про події через emit. Оголошувати події не обов'язково технічно, але дуже бажано.
<script setup>
const emit = defineEmits(['save', 'cancel']);
function onSubmit() {
emit('save', { title: title.value });
}
</script>
<PostForm @save="createPost" @cancel="close" />
Чому оголошувати:
- документація інтерфейсу: видно, які події компонент генерує, - як props для вхідних даних;
- відсутність подвійних спрацювань: неоголошена подія прокидається як нативний слухач на кореневий елемент. Якщо дитина робить
emit('click'), аclickне оголошено, обробник батька спрацює і від нативного кліку, і відemit- двічі; - TypeScript перевіряє назви й типи параметрів подій.
Валідація параметрів - об'єктний синтаксис:
const emit = defineEmits({
save: (payload) => {
if (!payload?.title) {
console.warn('Подія save без title');
return false;
}
return true;
},
cancel: null, // без перевірки
});
Невдала перевірка лише виводить попередження в режимі розробки - подія все одно відправляється. Це інструмент налагодження, а не захист.
З TypeScript - типова сигнатура, що краще за валідатори:
const emit = defineEmits<{
save: [payload: { title: string }];
cancel: [];
}>();
Іменування: у скрипті - camelCase (emit('itemSelected')), у шаблоні батька можна писати kebab-case (@item-selected) - Vue перетворює автоматично.
Чим події компонентів відрізняються від подій DOM:
- не спливають - подію дитини чує лише її безпосередній батько. Для передачі через кілька рівнів - повторний
emitна кожному рівні,provide/injectз функцією або стор; - синхронні: обробники батька виконуються в момент
emit.
emit у setup поза <script setup> - другий аргумент setup(props, { emit }).