Black Friday Killer Deal
Get the Ultimate Vue Bundle for 64% Off

All the courses you need to master Vue ecosystem + the certificate to prove it

Get the Offer

This content is also available as a quick video tutorial.

Vue event handling is a necessary aspect of every Vue project. It’s used to capture user input, share data, and so many other creative ways.

In this article, I’ll be going over the basics and providing some code examples for working with events. It will just include the tips/methods that I find the most useful, for an indepth look at all the things Vue can do, check out the Vue docs.

Basic Event Handling

Using the v-on directive (@ for short) we can listen to DOM events and run either a handler method or inline JavaScript

<div v-on:click="handleClick" />

<div @click="handleClick" />

We’ll be covering some of the more common events that you may want to capture, click here for a complete list of DOM events.

Emitting custom events

A common use case in any web framework is wanting a child component to be able to emit an event to its parent. This will allow for two-way data binding.

One example of this is sending data from an input component to the parent form.

Depending on if we are using the Options API or the Composition API, the syntax for emitting events is different.

In the Options API, we can simply call this.$emit(eventName, payload)

Our example of our component might look like this.

export default {
  methods: {
    handleUpdate: () => {
      this.$emit('update', 'Hello World')
    },
  },
}

However, the Composition API has a different this reference. Instead, we can use the Vue 3 setup methodto directly access the emit method.

The second argument for the setup method is the context variable which contains three properties: attrs, slots, and most importantly for us, emit.

As long as we import our context object, we can call emit using the same arguments as the Options API.

export default {
  setup(props, context) {
    const handleUpdate = () => {
      context.emit('update', 'Hello World')
    }

    return { handleUpdate }
  },
}

One way to tidy up our code is to import emit directly using object destructuring. That would look something like this.

export default {
  setup(props, { emit }) {
    const handleUpdate = () => {
      emit('update', 'Hello World')
    }

    return { handleUpdate }
  },
}

Awesome.

Regardless if we use the Options or Composition API, our parent component listens to our event the same way.

<HelloWorld @update='inputUpdated'/>

If the method we emit also passes a value, we can capture it in two different ways – depending if we are working inline or with another method.

First, we can access the passed value using $event in our template.

<HelloWorld @update="inputUpdated($event)" />

Second, if we use a method to handle our event, the passed value will be automatically passed as the first argument to our method.

<template>
  <HelloWorld @update="inputUpdated" />
  <template>
    <script>
      // ...
      methods: {
        inputUpdated: (value) => {
          console.log(value) // WORKS TOO
        }
      }
    </script></template
  >
</template>

Handling mouse modifiers

Here are a list of the primary DOM mouse events that we can capture in our v-on directive:

<div
  @mousedown='handleEvent'
  @mouseup='handleEvent'
  @click='handleEvent'
  @dblclick='handleEvent'
  @mousemove='handleEvent'
  @mouseover='handleEvent'
  @mousewheel='handleEvent'
  @mouseout='handleEvent'
>
Interact with Me!
</div>

For our click events, we can also add mouse event modifiers to limit which mouse buttons will trigger our event. There are three (one for each button): left, right, and middle.

<!-- This will only trigger for the left mouse click -->
<div @mousedown.left='handleLeftClick'> Left </div>

Key Modifiers

There are three DOM keyboard events that we can listen to

<input
   type='text'
   placeholder='Type something'
   @keypress='handleKeyPressed'
   @keydown='handleKeyDown'
   @keyup='handleKeyUp'
/>

Often, we want to detect these events on a certain key, there are two ways to do this.

  • keycodes
  • Vue has aliases for certain keys (enter, tab, delete, esc, space, up, down, left, right)
<!-- Trigger even when enter is released -->
<input
   type='text'
   placeholder='Type something'
   @keyup.enter='handleEnter'
/>

<!-- OR -->
<input
   type='text'
   placeholder='Type something'
   @keyup.13='handleEnter'
/>

System Modifiers

For certain projects, we may only want to trigger events if a user is pressing down a modifier key. A modifier key is something like command or shift.

In Vue, there are four system modifiers.

  • shift
  • alt
  • ctrl
  • meta (cmd on macs and the windows key on windows)

This can be extremely useful for creating features like custom keyboard shortcuts inside your Vue application.

<!-- Custom Shortcut that creates a list for Shift + 8 -->
<input
   type='text'
   placeholder='Type something'
   @keyup.shift.56='createList'
/>

Going through the Vue docs, there is also an exact modifier, ensuring that the event will only be triggered if only the keys we specify are pressed and no others.

<!-- Custom Shortcut that creates a list for Shift + 8 ONLY -->
<input
   type='text'
   placeholder='Type something'
   @keyup.shift.56.exact='createList'
/>

Event Modifiers

For all DOM events, we can use some modifiers that change how they run. Whether it’s stopping propagation or prevent the default action, Vue has a couple of built in DOM event modifiers.

<!-- Prevent Default Action -->
<form @submit.prevent>

<!-- Stop Event Propagation -->
<form @submit.stop='submitForm'>

<!-- Easy to Join Modifiers -->
<form @submit.stop.prevent='submitForm'>

<!-- Prevent event from being triggered more than once -->
<div @close.once='handleClose'>

Conclusion

Hopefully, this short cheatsheet gave you a better view of Vue event handling and what’s possible.

As always, I recommend also checking out the Official Vue Documentation for a more in-depth look at the features of Vue event handling.

Happy coding!