Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як типізувати події компонента через defineEmits?

defineEmits оголошує, які події компонент може випромінювати і з якими аргументами.

Сучасний синтаксис (Vue 3.3+) - іменовані кортежі:

<script setup lang="ts">
const emit = defineEmits<{
  change: [id: number]
  update: [value: string, source: 'keyboard' | 'paste']
  close: []
}>()

emit('change', 42)
emit('update', 'текст', 'paste')
emit('change', 'abc')   // помилка TypeScript
emit('unknown')         // помилка TypeScript
</script>

Старіший синтаксис - сигнатури викликів, працює так само:

const emit = defineEmits<{
  (e: 'change', id: number): void
  (e: 'close'): void
}>()

Батьківський компонент отримує перевірку типів у шаблоні: @change="(id) => select(id)" - id має тип number, а підписка на неоголошену подію підсвічується редактором (з розширенням Vue - Official і vue-tsc).

Навіщо оголошувати події взагалі:

  • документація компонента: з першого рядка видно його «вихідний» інтерфейс;
  • атрибути-слухачі не протікають на корінь: оголошена подія не потрапляє у $attrs. Неоголошена - потрапляє і може навісити нативний обробник на кореневий елемент, через що @click спрацює двічі;
  • перевірка в режимі розробки: з runtime-валідацією (об'єктний синтаксис з функціями-валідаторами) Vue попередить про некоректне корисне навантаження.

Типові помилки:

  • події в стилі camelCase і kebab-case: у шаблоні батька пишуть @item-selected, у дочірньому emit('itemSelected') - Vue їх зіставляє, але в типах і пошуку по коду краще одна форма;
  • зміна props замість події: дочірній компонент мутує об'єкт із props («він же не примітив, працює») - потік даних стає непрозорим. Зміну даних батька - лише через подію чи defineModel;
  • занадто багато подій - знак, що компонент робить забагато або що частину стану варто винести в стор.

Докладніше в документації: TypeScript: типізація emits

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання