Курсы Блог Обо мне
⬅️ Назад к курсу

Что такое Emits?

reactive

Emits — это механизм Vue для передачи событий от дочернего компонента к родительскому. В TypeScript мы добавляем строгую типизацию для надежности кода.

Базовое использование Emits

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

<template>
  <button @click="handleClick">Отправить событие</button>
</template>

<script setup lang="ts">
// Определяем типы для emits
const emit = defineEmits<{
  (e: 'submit', payload: string): void
  (e: 'update', id: number): void
}>()

const handleClick = () => {
  emit('submit', 'Данные для родителя')
}
</script>

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

<template>
  <ChildComponent 
    @submit="handleSubmit"
    @update="handleUpdate"
  />
</template>

<script setup lang="ts">
const handleSubmit = (payload: string) => {
  console.log('Получено:', payload) // "Данные для родителя"
}

const handleUpdate = (id: number) => {
  console.log('ID:', id)
}
</script>

Валидация событий

Можно добавить проверку передаваемых данных

<script setup lang="ts">
const emit = defineEmits<{
  (e: 'submit', payload: string): boolean
}>()

const handleClick = () => {
  if (!emit('submit', 'test')) {
    console.error('Валидация не пройдена!')
  }
}
</script>

Комплексный пример с TypeScript

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

<template>
  <input 
    :value="modelValue"
    @input="emitValue($event.target.value)"
  />
</template>

<script setup lang="ts">
interface Props {
  modelValue: string
}

interface Emits {
  (e: 'update:modelValue', value: string): void
  (e: 'submit'): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const emitValue = (value: string) => {
  emit('update:modelValue', value)
  
  if (value.length > 5) {
    emit('submit')
  }
}
</script>

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

<template>
  <FormInput
    v-model="inputValue"
    @submit="handleSubmit"
  />
</template>

<script setup lang="ts">
const inputValue = ref('')

const handleSubmit = () => {
  alert(`Отправлено: ${inputValue.value}`)
}
</script>

Лучшие практики

Используйте kebab-case в шаблоне

<ChildComponent @custom-event="handler" />

Типизация сложных объектов

interface User {
  id: number
  name: string
}

defineEmits<{
  (e: 'user-update', user: User): void
}>()

Опциональные параметры

defineEmits<{
  (e: 'event', payload?: string): void
}>()

Заключение

Домашнее задание: базовые emits

Создайте компонент CounterButton, который:

<!-- CounterButton.vue -->
<script setup lang="ts">
// Ваш код здесь
</script>

<template>
  <button @click="handleClick">
    {{ count }}
  </button>
</template>

Проверка

<template>
  <CounterButton 
    :initialValue="5" 
    @update="(val) => console.log(val)" 
  />
</template>

При клике должно выводить в консоль: 6, 7, 8…

frontline

FrontLine

Присоединяйтесь к нам в телеграмм

Другие интересные посты в удобном в формате

Подписаться

Другие уроки