Javascript is required
Michael Hoffmann LogoMichael Hoffmann

Vue Tip: Event Handling

Michael Hoffmann - Senior Frontend Developer (Freelancer)
Michael Hoffmann
Sep 23, 2023
1 min read
|
27 views
Template
Script
Vue Tip: Event Handling Image

In Vue, you can listen for events using the v-on directive or the shorthand @. You can listen for any DOM event; for example, you can use @click for click events. This link contains a list of all native DOM events.

Define Events

Of course, you can also listen for custom events that you have defined in your child component:

Child.vue
1
<script setup lang="ts">
2
import { ref } from 'vue'
3
4
const counter = ref(0)
5
6
const emit = defineEmits<{
7
(event: 'update:counter', counter: number): void
8
}>()
9
10
const increment = () => {
11
counter.value++
12
emit('update:counter', counter.value)
13
}
14
</script>
15
16
<template>
17
<div>
18
<span>Counter: {{ counter }}</span>
19
<button @click="increment">Increment</button>
20
</div>
21
</template>

Handle Events

Let's look at the different ways to handle such events in Vue.

Without arguments

If your event does not have any arguments, I prefer this syntax:

Parent.vue
1
<script setup lang="ts">
2
import Child from './Child.vue'
3
4
const onUpdateCounter = (counter: number) => {
5
console.log('onUpdateCounter', counter)
6
}
7
</script>
8
9
<template>
10
<Child @update:counter="onUpdateCounter" />
11
</template>

Access custom event object

If you want to access the custom event object in your event handler, you can use the following syntax:

Parent.vue
1
<script lang="ts" setup>
2
import type { Counter } from '...'
3
4
const counters: Counter[] = [
5
// ...
6
]
7
8
function onUpdateCounter(counter: Counter) {
9
// ...
10
}
11
</script>
12
13
<template>
14
<ul>
15
<li v-for="counter of counter" :key="counter.id">
16
<Child @update:counter="() => onUpdateCounter(counter)" />
17
</li>
18
</ul>
19
</template>

Access custom & native event object

Sometimes, you need access to your custom event object and the native event object. In this case, you can use the following syntax:

Parent.vue
1
<script lang="ts" setup>
2
import type { Counter } from '...'
3
4
const counters: Counter[] = [
5
// ...
6
]
7
8
function onUpdateCounter(event: Event, counter: Counter) {
9
// ...
10
}
11
</script>
12
13
<template>
14
<ul>
15
<li v-for="counter of counter" :key="counter.id">
16
<Child @update:counter="($event) => onUpdateCounter($event, counter)" />
17
</li>
18
</ul>
19
</template>

Further Reading

Lachlan Miller wrote an excellent in-depth article about event handling, which you can find here. It is definitely worth a read!


If you liked this Vue tip, follow me on Twitter to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue newsletter:

New Vue & Nuxt tips delivered to your inbox:
I will never share any of your personal data.