A Guide to Events in Vue

Johnny Simpson - May 11 '22 - - Dev Community

As with any framework, Vue lets us add reactivity to our applications and websites through events. The great thing about Vue events is they mimic vanilla Javascript, so all the events you're used to using in Javascript can also be used in Vue.

Vue Basics

If you are brand new to Vue, I would recommend reading my guide on making your first Vue application, or creating components in Vue first.

Events in Vue

The most basic event frequently used in Vue, as well as in most Javascript, is click. The component below is a simple counter which increases by 1 every time the button is clicked. To do this, we use an inline @click event:

<script>
export default {
    data() {
        return {
            counter: 0
        }
    }
}
</script>
<template>
    <button @click="++counter">
        {{ counter }}
    </button>
</template>
Enter fullscreen mode Exit fullscreen mode

Since we can write inline Javascript straight into our events, we can simply write ++counter to increase our counter data. As such, the above will increase counter any time we click the button, and display that in our button element.

As mentioned before, we aren't just limited to @click. All other Javascript events work too, in the same format. That means you can use:

  • @keydown
  • @mousedown
  • @pointerdown
  • @pointerup
  • @scroll
  • etc..

We aren't just limited to running Javascript inline in our events. We can trigger a method or function, if one is defined in our Vue Javascript. Here is the same code using a method instead:

<script>
export default {
    data() {
        return {
            counter: 0
        }
    },
    methods: {
        incrCounter: function() {
            ++this.counter
        }
    }
}
</script>
<template>
    <button @click="incrCounter">
        {{ counter }}
    </button>
</template>
Enter fullscreen mode Exit fullscreen mode

v-on vs @ in Vue

You may have seen events written as v-on:click vs @click. Both of these mean the same thing, and are interchangable, so use whichever one you are comfortable with!

Mouse Specific EVents

We can further modify any mouse events by using the left, middle, and right modifiers. If we are firing a mouse related event, like click, or mousedown, then mousedown.right will only track right mouse clicks, or mousedown.middle will only track middle mouse clicks.

<!-- left mouse clicks -->
<button @mousedown.left="incrCounter">
    {{ counter }}
</button>
<!-- right mouse clicks -->
<button @mousedown.right="incrCounter">
    {{ counter }}
</button>
<!-- middle mouse clicks -->
<button @mousedown.middle="incrCounter">
    {{ counter }}
</button>
Enter fullscreen mode Exit fullscreen mode

Using Event Data in Vue Events

Sometimes, we want to access the event or e object in our events. In situations where we simply want to access e itself with no other arguments, we don't have to mention e - it is automatically passed directly to the function. For example, the code below will still console log e.clientX and e.clientY whenever the user clicks the button:

<script>
export default {
    data() {
        return {
            counter: 0
    }
  },
  methods: {
    incrCounter: function(e) {
      ++this.counter
      console.log(e.clientX, e.clientY)
    }
  }
}
</script>

<template>
    <button @click="incrCounter">
    {{ counter }}
  </button>
</template>
Enter fullscreen mode Exit fullscreen mode

Things become a little tricker when you have more than 2 arguments. In these situations, there are two ways to access event data. Either encapsulate the function, or use the predefined $event variable.

For example, let's say we want to increase the counter by a custom amount, and continue to console log e.clientX and e.clientY. This is achievable by using $event to pass the event data to our function:

<script>
export default {
    data() {
        return {
            counter: 0
        }
    },
    methods: {
        incrCounter: function(amount, e) { 
            ++this.counter
            console.log(e.clientX, e.clientY)
        }
    }
}
</script>

<template>
    <button @click="incrCounter(5, $event)">
        {{ counter }}
    </button>
</template>
Enter fullscreen mode Exit fullscreen mode

Alternatively, we could also pass the e object directly to the function as follows:

<button @click="(e) => incrCounter(5, e)">
    {{ counter }}
</button>
Enter fullscreen mode Exit fullscreen mode

Custom Key Events in Vue Events

Vue tries to simplify events as much as possible. If you've ever made key events in the past, you'll know that frequently we only want to access a specific key. Therefore, with key events, we can tie common keys directly to the event. For example, in this input, we will fire an event any time the user presses a keyup event:

<input @keyup="someFunction" />
Enter fullscreen mode Exit fullscreen mode

But if we want to fire the @keyup only when the user presses enter, we can do that with the following event:

<input @keyup.enter="someFunction" />
Enter fullscreen mode Exit fullscreen mode

We can use any defined keyboard key value, converted to kebab case. For example, PageDown is a keyboard key defined value, but in Vue we write page-down:

<input @keyup.page-down="someFunction" />
Enter fullscreen mode Exit fullscreen mode

Finally, Vue has defined some commonly used keys which are not defined values. These are enter, tab, delete, esc, space, up, down, left, right, as well as the keyboard modifiers ctrl, alt, shift and meta.

Keyboard modifiers and keys

We just mentioned the keyboard modifiers ctrl, alt, shift and meta, and these can actually be combined with our key values from before, to add another layer of functionality. For example, the below will fire the keydown event, and therefore someFunction, whenever shift and enter are both pressed within the input:

<input @keydown.shift.enter="someFunction" />
Enter fullscreen mode Exit fullscreen mode

Exact modifier

Finally, we can make sure only one key is being pressed by using exact. The below, for example, will only fire if enter is pressed alone. If enter is pressed with a combination of other keys, the event will not fire:

<input @keydown.enter.exact="someFunction" />
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Event control in Vue is an essential element to building any complete Vue application. I hope you've enjoyed this guide. You can find more Vue content here.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .