Events are used to communicate from a child component back to a parent component.

To listen to any event on a child component instance use v-on directive, or the shorthand @

<BlogPost
  ...
  @enlarge-text="postFontSize += 0.1"
 />


the child component can emit an event on itself by calling the built-in $emit method:

<!-- BlogPost.vue, omitting <script> -->
<template>
  <div class="blog-post">
    <h4>{{ title }}</h4>
    <button @click="$emit('enlarge-text')">Enlarge text</button>
  </div>
</template>

defineEmits

Optionally emitted events can be declared using defineEmits macro that documents all emitted events and can validate them.
It is sonly usable in <script setup> and returns an emit function that is the equivalent of $emit but can be used in <script setup>

<script setup>
const emit = defineEmits(['enlarge-text'])
 
emit('enlarge-text')
</script>

Event Arguments

To emit an argument alongside an event we can pass extra arguments to $emit

<button @click="$emit('increaseBy', 1)"> Increase by 1 </button>

Event Handler Types

Inline Event Handlers

For simple cases, the code for handling the event can be placed directly in the directive

const count = ref(0)
<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>

To accept arguments in inline handlers we can use arrow functions:

<MyButton @increase-by="(n) => count += n" />

Method Event Handlers

For more complex cases the v-on directive can take name or path of a component method

const name = ref('Vue.js')
 
function greet(event) {
  alert(`Hello ${name.value}!`)
}
<!-- `greet` is the name of the method defined above -->
<button @click="greet">Greet</button>

To be treated as method handler need to be in one of the forms foo, foo.bar or foo['bar']. As foo() would be treated as an inline handler

Emitted arguments will be passed to method handlers as function arguments.

Calling Methods in Inline Handlers

Methods can also be called in an inline handler, allowing us to pass custom arguments instead of native events

function say(message) {
	alert(message)
}
<button @click="say('hello')">Say hello</button>

Accessing the DOM Event

Sometimes we need access to the original DOM event .

Method Handlers

Method handlers automatically receive the event object:

const name = ref('Vue.js')
 
function greet(event) {
  alert(`Hello ${name.value}!`)
  // `event` is the native DOM event
  if (event) {
    alert(event.target.tagName)
  }
}
<!-- `greet` is the name of the method defined above -->
<button @click="greet">Greet</button>

Where the event.target is the native DOM event object triggering the handler.

Inline Handlers

In inline handlers we can pass the event with a special $event variable, or by using an inline arrow function

<!-- using $event special variable -->
<button @click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
 
<!-- using inline arrow function -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">
  Submit
</button>
function warn(message, event) {
  // now we have access to the native event
  if (event) {
    event.preventDefault()
  }
  alert(message)
}

Event Modifiers

To access functionality like event.preventDefault() or event.stopPropagation() inside event handlers without having to deal with DOM event details Vue provides event modifiers

The available modifiers are:

  • .stop
  • .prevent
  • .self
  • .capture
  • .once
  • .passive

Examples

<!-- the click event's propagation will be stopped -->
<a @click.stop="doThis"></a>
 
<!-- the submit event will no longer reload the page -->
<form @submit.prevent="onSubmit"></form>
 
<!-- modifiers can be chained -->
<a @click.stop.prevent="doThat"></a>
 
<!-- just the modifier -->
<form @submit.prevent></form>
 
<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div @click.self="doThat">...</div>
 
<!-- use capture mode when adding the event listener     -->
<!-- i.e. an event targeting an inner element is handled -->
<!-- here before being handled by that element           -->
<div @click.capture="doThis">...</div>
 
<!-- the click event will be triggered at most once -->
<a @click.once="doThis"></a>
 
<!-- the scroll event's default behavior (scrolling) will happen -->
<!-- immediately, instead of waiting for `onScroll` to complete  -->
<!-- in case it contains `event.preventDefault()`                -->
<div @scroll.passive="onScroll">...</div>

Order Matters

The code generated from the modifiers follows the same order as the modifiers themselves, so @click.prevent.self will prevent click’s default action on the element and it’s children while @click.self.prevent will **prevent click’s action on only the element itself **

Key Modifiers

Checking for specific keyboard events can be done by adding key modifiers to the v-on directive

for example:

<!-- only call `submit` when the `key` is `Enter` -->
<input @keyup.enter="submit" />

Any valid key names exposed via KeyboardEvent.key can be used as modifiers when converted to kebab-case, but Vue also provides aliases for the commonly used keys:

  • .enter
  • .tab
  • .delete (captures both “Delete” and “Backspace” keys)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

System Modifier Keys

The following modifiers cause mouse or keyboard events to only be triggered when the modifier key is pressed:\

  • .ctrl
  • .alt
  • .shift
  • .meta

for example:

<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />
 
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

The modifier keys work differently from regular keys and only emit keyup events when another key is released while holding down the modifier key

.exact Modifier

This modifier allows to control the exact combination of system modifiers needed to trigger an event:

<!-- this will fire even if Alt or Shift is also pressed -->
<button @click.ctrl="onClick">A</button>
 
<!-- this will only fire when Ctrl and no other keys are pressed -->
<button @click.ctrl.exact="onCtrlClick">A</button>
 
<!-- this will only fire when no system modifiers are pressed -->
<button @click.exact="onClick">A</button>

Mouse Button Modifiers

The mouse button modifiers are:

  • .left
  • .right
  • .middle