Courses Blog About
⬅️ Back to the course

What are Emits?

reactive

Emits is a Vue mechanism for passing events from a child component to a parent component. In TypeScript, we add strong typing for code reliability.

Basic usage of Emits

Child component ChildComponent.vue

<template>
  <button @click="handleClick">Send an event</button>
</template>

<script setup lang="ts">
// Defining types for emits
const emit = defineEmits<{
  (e: 'submit', payload: string): void
  (e: 'update', id: number): void
}>()

const handleClick = () => {
  emit('submit', 'Data for the parent')
}
</script>

Parent component

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

<script setup lang="ts">
const handleSubmit = (payload: string) => {
  console.log('Получено:', payload) // "Data for the parent"
}

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

Event validation

You can add verification of the transmitted data.

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

const handleClick = () => {
  if (!emit('submit', 'test')) {
    console.error('Validation failed!')
  }
}
</script>

Comprehensive TypeScript example

Child component Form Input.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>

Parent component

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

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

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

Best practices

Use kebab-case in the template

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

Typing complex objects

interface User {
  id: number
  name: string
}

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

Optional parameters

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

Conclusion

Homework: Basic emits

Create a CounterButton component that:

<!-- CounterButton.vue -->
<script setup lang="ts">
// Your code is here
</script>

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

Check

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

When clicked, it should output to the console: 6, 7, 8…

frontline

FrontLine

Join us in telegram

Other interesting posts in a convenient format

Subscribe

Another lessons