Introduction
Event handling is a very important concept when trying to make an interactive application. Generally speaking, an event is a signifier of an interaction between a user and our application - clicking, typing on a keyboard, and so on. Interactive and reactive applications are, in essence, built around the concept of reacting to events - each time an event is detected, an application calls a corresponding function that handles the detected event.
These functions are known as event handlers.
Vue is no different. It has an event handling mechanism that allows you to catch and handle events from within each independent component file. Events can appear either as user input or we can manually create them in the code and emit them when needed.
In this article, we will explore how to handle events in Vue using the
v-on
directive. Event handling enables us to run JavaScript as a response to DOM events. We will learn how to handle the click, submit, scroll, and some keyboard events.
v-on Directive in Vue
Vue uses the v-on
directive to catch and handle events. It defines a DOM event it listens to and assigns a JavaScript function that runs when the event is detected:
<div v-on:click="handleClick"/>
<div @click="handleClick"/>
Note: The v-on
directive is used interchangeably with the @
symbol - v-on:event-name
is equal to @event-name
.
Common Events in Vue
There are lots of events that can be captured! Though, not all of them are used on a daily basis. The majority of the events you'll be tracking commonly can be divided into three categories: mouse, keyboard, and form events.
Each one of them has some specific distinctions, so let's take a deeper look at each individual group and how to handle them.
Mouse Events in Vue
Mouse events are triggered each time a user clicks, drags, drops, or does something with a mouse to a particular item. For example, the following code will prompt an alert when a user clicks a button using v-on:click
:
<div>
<!-- `v-on:click` detects the click event -->
<button v-on:click="showAlert('Thank you for clicking the button!')" >
Show alert
</button>
</div>
<script>
export default {
methods: {
showAlert: (message) => {
alert(message);
}
}
};
</script>
Alternatively, we can make use of the @
symbol and avoid using v-on
as seen below:
<div>
<button @click="showAlert('Thank you for clicking the button!')">
Show alert
</button>
</div>
Keyboard Events in Vue
Keyboard events are triggered when a user types a particular button on the keyboard. You can register an event when a user is pressing down a key (keydown
), starts to presses a key (keypress
), or releases a key (keyup
):
<input type='text' placeholder='Type something' @keypress='handleKeyPressed' @keydown='handleKeyDown' @keyup='handleKeyUp' />
For instance, suppose we want an alert to show what is typed into an input field when we press the enter key on our keyboard. This can be achieved easily using @keyup.enter
:
<div>
<input type="text" v-model="name" @keyup.enter="showAlert(name)" />
</div>
<script>
export default {
data() {
return {
name: ""
};
},
methods: {
showAlert: (message) => {
alert(message);
}
}
};
</script>
Taking a look at the code above, you will notice we added key event modifiers - such as .enter
. Key event modifiers in Vue offer extensive support for listening to keyboard inputs.
The key event modifier follows the structure:
v-on.keyevent.keyname
// Or
v-on.keyevent.keycode
Note: Keycodes are generally deprecated and you should avoid using them because most modern browsers don't support them anymore. It's only reasonable to use them for legacy reasons - if you need to support old browsers that don't have support for key name modifiers.
Vue makes your job easier by providing aliases for the most commonly used key codes - .enter
, .tab
, .delete
(encapsulates "Delete" and "Backspace" keys), .esc
, .space
, .up
, .down
, .left
, .right
.
Either way, you should use key names instead of keycodes whenever possible - that's a way to future-proof your code!
Key names follow the simple naming convention in Vue. The first thing you should know is that you can find all valid key names in KeyboardEvent.key
. Those names use camel casing (e.g. CapsLock
), but key names in Vue use kebab casing (e.g. caps-lock
).
So, to find a valid Vue key name, take a look at its name in KeyboardEvent.key
and convert it to a kebab case. As simple as that!
Note: You can also chain multiple key names like v-on.keyup.ctrl.enter
.
In case you must use keycodes, again, you can, even though it's not advised:
<input type="text" v-model="name" @keyup.13="showAlert(name)" />
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
The 13th key is "Enter".
Note: You can check for keycodes here.
Form Events in Vue
Form events are triggered by form actions such as submission, input field change and lots more - using event names like :submit
, :change
, :reset
. The following code illustrates how you can pop an alert message when form data is submitted:
<form className="new-task" @submit="handleSubmit">
<input
type="text"
placeholder="Type to add new tasks"
v-model="newTask"
/>
</form>
<script>
export default {
data() {
return {
newTask: ""
};
},
methods: {
handleSubmit() {
alert(this.newTask);
}
}
};
</script>
One thing you should keep in mind when managing form submissions in JavaScript apps is that you must utilize the native preventDefault()
function of the submit event before running your form handling function. Otherwise, the page will be redirected before the form validation function has a chance to validate a form. This is because by default, the next expected action is forwarding the data to a server's REST API, which we don't have here.
This is easily accomplished with Vue by adding a prevent
event modifier directly to the form template, rather than doing it manually in your handler. When added, a prevent
modifier makes sure the submit event won't reload the page. It's worth noting that the modifier is inserted after the .
in the directive:
<form @submit.prevent="handleSubmit"></form>
Vue offers several event modifiers that are useful in common event handling scenarios:
.stop
- stop propagation of click events:
<a v-on:click.stop="doThis"></a>
.capture
- an event targeting a child element, within a parent element is handled by the parent first, before being delegated to the child:
<div v-on:click.capture="doThis"></div>
There are others like .self
, .once
, .passive
, etc.
Note: Modifiers can be chained as well. For example v-on:click.stop.prevent="handleClick"
.
Writing and Emitting Custom Events in Vue
So far, we've discussed handling native events. Now, let's look at how to make a component emit its own event, given that Vue is a component-based framework.
Assume we want a child component to convey information to a parent component. Prop data can only be sent from parent to child, not the other way around, therefore we can't utilize it here. A solution is for the child component to emit an event and the parent to listen for it.
When you want the event to be emitted, use this.$emit("my-event-name")
from the child component. Assume we have a component ChildComponent
that must notify its parent MainPage
that it has been closed.
ChildComponent
export default {
methods: {
onClose() {
this.$emit('close-dialog');
},
},
};
Additionally, you can also send data in your custom event. MainPage
can access that data in the handler function of the close-dialog
event:
onClose() {
this.$emit("close-dialog", { time: Date.now() });
}
MainPage
The parent component (MainPage
) can then handle the custom event exactly the same as it would for a native event.
<div>
<dialog-component @close-dialog="handleEvent" />
</div>
Event handler can access data sent when the close-dialog
event was emitted:
handleEvent ({ time }) {
console.log(`The Dialog was closed at ${time}`);
}
Conclusion
In this article, we've learned how to handle events in Vue using v-on
. We've explained the most common types of events - mouse events, form events, and keyboard events.
Additionally, we've explained how to create custom events in Vue. After reading this article, you should have a comprehensive overview of event handling in Vue, you should be able to handle all native events, and be able to create your own custom events from starch.