Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/native-event-collision-with-emits.md
1---2title: Declaring Native Event Names in Emits Blocks Native Listeners3impact: MEDIUM4impactDescription: Declaring native events like 'click' in emits prevents native DOM event listeners from working5type: gotcha6tags: [vue3, emits, native-events, click, event-collision]7---89# Declaring Native Event Names in Emits Blocks Native Listeners1011**Impact: MEDIUM** - When you declare a native DOM event name (like `click`, `input`, `focus`) in your component's `emits` option, listeners for that event will ONLY respond to your component's `emit()` calls. They will no longer respond to the actual native DOM events on the root element.1213This can cause unexpected behavior where clicks seem to stop working on your component.1415## Task Checklist1617- [ ] Understand that declaring native event names changes listener behavior18- [ ] Always emit the event when you declare it19- [ ] Don't declare native events if you want fallthrough behavior20- [ ] Test click/input handling after adding emits declarations2122## The Problem2324**Incorrect - Declaring but not emitting:**25```vue26<!-- ClickableCard.vue -->27<script setup>28// Declared 'click' but never emit it!29const emit = defineEmits(['click', 'select'])30</script>3132<template>33<div class="card">34<slot></slot>35</div>36</template>37```3839```vue40<!-- Parent.vue -->41<template>42<!-- This NEVER fires! Native clicks are blocked -->43<ClickableCard @click="handleClick">44Click me45</ClickableCard>46</template>47```4849**Why it fails:**501. `click` is declared in `emits`512. Vue treats `@click` as a component event listener523. Native click on the `<div>` doesn't trigger component event534. Since `emit('click')` is never called, handler never fires5455## The Solution5657**Option 1: Emit the event explicitly:**58```vue59<!-- ClickableCard.vue -->60<script setup>61const emit = defineEmits(['click', 'select'])62</script>6364<template>65<!-- Explicitly emit click when div is clicked -->66<div class="card" @click="emit('click', $event)">67<slot></slot>68</div>69</template>70```7172**Option 2: Don't declare native events (use fallthrough):**73```vue74<!-- ClickableCard.vue -->75<script setup>76// Only declare custom events, not native ones77const emit = defineEmits(['select', 'custom-action'])78</script>7980<template>81<!-- Native @click from parent falls through to this div -->82<div class="card">83<slot></slot>84</div>85</template>86```8788```vue89<!-- Parent.vue -->90<template>91<!-- Native click falls through and works -->92<ClickableCard @click="handleClick">93Click me94</ClickableCard>95</template>96```9798## Native Events Affected99100This applies to any native DOM event you might declare:101102| Event | Behavior When Declared |103|-------|----------------------|104| `click` | Only responds to `emit('click')`, not native clicks |105| `input` | Only responds to `emit('input')`, not native input |106| `change` | Only responds to `emit('change')`, not native change |107| `focus` | Only responds to `emit('focus')`, not native focus |108| `blur` | Only responds to `emit('blur')`, not native blur |109| `submit` | Only responds to `emit('submit')`, not native form submit |110| `keydown` | Only responds to `emit('keydown')`, not native keydown |111112## When This Is Intentional113114Sometimes you WANT to intercept native events:115116```vue117<!-- CustomInput.vue -->118<script setup>119// Intentionally intercept 'input' to transform the value120const emit = defineEmits(['input', 'update:modelValue'])121122function handleInput(event) {123const transformedValue = event.target.value.toUpperCase()124emit('input', transformedValue) // Emit transformed value, not raw event125emit('update:modelValue', transformedValue)126}127</script>128129<template>130<input @input="handleInput" />131</template>132```133134Here, declaring `input` is correct because you want to intercept and transform the native event before passing it to the parent.135136## Debugging Tips137138If your click handlers aren't firing:1391401. Check if the event is declared in `emits`1412. If declared, ensure you're calling `emit('click')` somewhere1423. If you want native behavior, remove from `emits` declaration1434. Use Vue DevTools to see which events are being emitted144145```vue146<script setup>147const emit = defineEmits(['click'])148149function handleClick(event) {150console.log('Native click received, now emitting component event')151emit('click', event)152}153</script>154155<template>156<div @click="handleClick">Click me</div>157</template>158```159160## Reference161- [Vue.js Component Events](https://vuejs.org/guide/components/events.html)162- [Vue.js Fallthrough Attributes](https://vuejs.org/guide/components/attrs.html)163