Chapter 92: Vue ’emits’ Option

The emits option

This is the official, clean, declarative way to tell Vue (and other developers reading your code):

“These are all the custom events that this component might emit to its parent.”

In other words: emits is your component’s public API contract for upward communication.

Before Vue 2.6 / Vue 3, there was no emits option → developers just called this.$emit(‘anything’) whenever they felt like it. That led to:

  • Typos in event names (update-usre instead of update:user)
  • No autocompletion / type safety
  • No warning when parent listens to non-existent events
  • Hard-to-maintain components (nobody knows what events exist)

Since Vue 2.6 (2019) and especially in Vue 3, the emits option became the recommended and eventually required way to declare events.

1. Two Main Forms of emits (Both still used in 2026)

A. Array form (simple, most common in small components)

JavaScript

→ Just a list of event names → Vue will warn in development mode if you emit something not in the list

B. Object form (with validation & type hints – preferred in larger apps)

JavaScript

In Vue 3 + TypeScript → almost nobody uses the object form anymore — they use defineEmits<…>() instead (see below).

2. Real, Complete Example – TodoItem with Multiple Emitted Events

Child: TodoItem.vue (Options API style – what you still see in legacy code)

vue

Parent – listening to emitted events

vue

3. Modern Vue 3 – Why We Almost Never Use emits: [ … ] Anymore

In <script setup> (the 2026 standard):

vue

→ No emits object → No this.$emit → Full TypeScript support (event names + payload types) → Autocompletion in template & code → Vue warns if you emit undeclared event

4. Important Rules & Gotchas (2026 Must-Know)

Rule / Gotcha Correct Behavior / Best Practice
emits is optional (but strongly recommended) Declare it — prevents typos & gives better Devtools/info
Event names should be kebab-case in template @update:user in template → emit(‘update:user’) in code
v-model support Emit ‘update:modelValue’ → enables <MyComp v-model=”value” />
Multiple v-model Emit ‘update:propName’ → enables v-model:title, v-model:body
Still used in 2026? Yes — in legacy Options API code, some plugins, interviews
Modern replacement defineEmits<…>() — type-safe & cleaner

Quick Summary Table – emits in 2026

Question Options API (legacy) Composition API (<script setup>) What you should do in new code
How to declare events? emits: [‘toggle’, ‘delete’] defineEmits<…>() Composition API
Emit an event this.$emit(‘toggle’, id) emit(‘toggle’, id)
TypeScript friendly? Poor Excellent (event names + payload types) Use defineEmits
Still used in 2026? Yes — legacy code, plugins, interviews Almost never (except legacy) Avoid unless maintaining old code

Final 2026 Advice from Real Projects

  • In new projectsnever write emits: [ … ] — use defineEmits<…>() in <script setup>
  • When you see emits as an array/object → it means Options API (legacy style)
  • Learn to read Options API — many jobs, open-source projects, tutorials still use it
  • Never teach beginners emits array as primary — start with defineEmits
  • If migrating old code → gradually convert this.$emit → emit(), emits: […] → defineEmits<…>()

Your mini homework:

  1. Create the TodoItem component above in Options API
  2. Use it in parent with @toggle and @delete
  3. Try emitting a typo event → see Vue warn in console (if declared)
  4. Convert it to <script setup> with defineEmits<…>() → compare type safety

Any part confusing? Want to see:

  • Full Options API vs Composition API emits comparison project?
  • How emits looks in Vue Devtools?
  • Common bugs when forgetting to declare events?
  • Real component with multiple v-model using update:propName?

Just tell me — we’ll convert and compare together step by step 🚀

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *