Introduction
Recently, I started learning VueJS, and this article is part of the series of my notes while learning it. In this one, I am covering how to use event handlers in the Vue.
On event directive
Vue comes with a directive that helps us handle many different types of events. That directive is a v-on directive. However, you can’t just write v-on, you need to tell somehow which type of event you are handling. You do that by adding a colon and event type after it.
v-on:[EVENT_TYPE]=”[HANDLER]”
This might be clearer with the example. So let's start with adding a function we can use for handling click events. In the initialization object, under methods, we can add the handleClick method.
Vue.createApp({
data() {
return {}
},
methods: {
handleClick: function() {
console.log("hello world")
}
}).mount("#app")
Now if you want to use this in your HTML all you need to do is add that v-on directive to some element. Click me
Handler code
In the example above, I used the handleClick() string as code for handling the event. However, there are some important things to note here. In the string, you can write your code, or you can use a reference to the function. If you are not passing reference to the function, then you could write one or more statements there, and imagine as if they are all wrapped in some function that Vue will run for you. This is important to understand for the next section where the event object is used.
<!-- function reference-->
<div>
<button type="button" v-on:click ="handleClick">
Click me
</button>
</div>
<!-- method call -->
<div>
<button type="button" v-on:click ="handleClick()">
Click me
</button>
</div>
<!-- single function call -->
<div>
<button type="button" v-on:click ="console.log('hello')">
Click other me
</button>
</div>
<!-- multiple functions call -->
<div>
<button type="button"
v-on:click ="console.log('hello'); console.log('other hello'); if(true) { console.log('another') }">
Click other me
</button>
</div>
Event object
Quite often when working with the events, you want to access the event object. Maybe to get access to the target element, prevent default behavior, or something else. When using this directive that is also possible. If you are using function reference for your event handler, the first parameter of the function is going to be the event object. Otherwise, code written between quotes will have access to the event object through the $event variable.
Accessing the event object in HTML
<!-- access to the event -->
<div>
<button type="button"
v-on:click ="console.log($event);">
Console event
</button>
</div>
Accessing event in methods when passing method reference
As said earlier, if you use method reference as the event handler, then you will get the event as the first parameter of it.
<!-- function reference-->
<div>
<button type="button" v-on:click ="handleClick">
Click me
</button>
</div>
Vue.createApp({
data() {
return {
}
},
methods: {
handleClick: function($event) {
console.log($event)
}
}
}).mount("#app")
Passing parameters and the event object
If you remember, above I wrote that you can imagine statements in the event handler being wrapped into function by Vue that will be run when needed. The reason why I am mentioning it is that quite often in the event handler, you want to both use the event object and some other data. You could write everything in your HTML, but that wouldn’t be very clean. So you can call the method and pass to it both the event object and any extra data as the code in the quotes does have access to the event object as well.
<div>
<button type="button"
v-on:click.stop.prevent="logEvent($event, 'extra data')">
Console event
</button>
</div>
I don’t recommend using the following code, as it is redundant and not clean, but to illustrate the point above, you could also write it in this way.
<div>
<button type="button"
v-on:.stop.prevent="function($event) {logEvent($event, 'extra data')">)}">
Console event
</button>
</div>
Handler modifiers
There are some common actions you might want to do with your events. Like preventing default behavior, stopping event propagation, or running it only with the click of a specific button. This directive does support that as well. You do that by adding dot-separated modifiers after the event type. In the following example, it will both run stopPropagation and preventDefault event methods on every event.
<div>
<button type="button" v-on:click.stop.prevent="handleClick">
Click me
</button>
</div>
As an additional example, in the below code, the event handler will run only if you click on it with the right mouse click. It also uses the prevent modifier to disable the default right-click popup.
<div>
<button type="button" v-on:click.stop.prevent.right="handleClick()">
Click me with right button
</button>
</div>
Other event types
In all of the examples above, I always used the click event. This was for the simplicity of the examples. But you can use other events as well. Not only that. You can even use multiple event directives on the same element as well.
<div>
<div>input element</div>
<input v-on:input="handleInput"
v-on:click="console.log('click')"
v-on:keyup="console.log('key up event')"
v-on:keyup.enter="console.log('key up enter event')"
v-on:click.prevent.right="console.log('right click')" type="text"/>
</div>
Alternative writing
If you are using a lot of event handlers, writing v-on: all the time can be repetitive. And in the Vue version 3, an alternative syntax was introduced. Instead of using the v-on:, you can replace it with the @ sign. Both options are fine, I would only suggest choosing one and sticking with it for consistency and using it everywhere in your project.
<div>
<button type="button" @click="console.log('using @')">
Using @ syntax
</button>
</div>
The code used in this article can be found in my GitHub repository.
For more, you can follow me on Twitter, LinkedIn, GitHub, or Instagram.