Listening to events is an important part of creating an interactive web app.
In this article, we’ll look at how to listening to events in a Vue app works so that we can make our app interactive by responding to them.
Listening to Events
We use the v-on directive to listen to DOM events and run some JavaScript code when the indicated event is triggered.
The most basic example would be something like the following:
index.js
:
new Vue({ el: "#app", data: { count: 0 } });
index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <button v-on:click="count += 1">Increment</button> <p>{{ count }}</p> </div> <script src="index.js"></script> </body> </html>
In the code above, we have the Vue instance with the data property with the count property that we want to update when we click on the button in index.html
.
The Increment button has the v-on:click directive that will increase count by 1 when we click it.
v-on
is directive and click is the event that we want to listen to with v-on .
Method Event Handlers
It’s rare that we only want to run only a small piece of code when we’re handling an event.
This is why we can attach an event listener function to run code.
For example, we can create a function to increase count
by 1 instead of putting the code straight in the template.
new Vue({ el: "#app", data: { count: 0 }, methods: { increment() { this.count += 1; } } });
index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <button v-on:click="increment">Increment</button> <p>{{ count }}</p> </div> <script src="index.js"></script> </body> </html> In the code above, we pass in the increment method from the methods property of the Vue instance in index.js into the template.Vue will call the function once the Increment button is clicked.Methods in Inline HandlersInstead of binding the click event directly to the method name, we can also call it. To do that we just make the following change in the template:index.html:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <button v-on:click="increment()">Increment</button> <p>{{ count }}</p> </div> <script src="index.js"></script> </body> </html>
Calling and not calling it to do the same thing, except that we can pass in arguments to our event handler function if we call it instead of just binding it to the name.
For instance, we can call it as follows:
index.js
:
new Vue({ el: "#app", methods: { greet(message) { alert(message); } } });
index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <button v-on:click="greet('hi')">Greet</button> </div> <script src="index.js"></script> </body> </html>
In the code above, we have:
<button v-on:click="greet('hi')">Greet</button>
We passed 'hi'
into the greet
method that we have in our Vue instance.
Accessing the Original DOM Element from Event Handlers
We can use the $event
object to access the DOM element that triggered the event.
For example, we can use it to get the ID of the element that triggered the click:
index.js
new Vue({ el: "#app", methods: { showAlert(id) { alert(`ID ${id} clicked`); } } });
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <button id="alert" v-on:click="showAlert($event.target.id)">Alert</button> </div> <script src="index.js"></script> </body> </html>
In the code above, we have:
v-on:click="showAlert($event.target.id)"
to get the ID from the button element and then show an alert box by calling the showAlert
method which calls the alert
function.
Event Modifiers
We can add modifiers after the event name argument to do some common operations like calling event.preventDefault() or event.stopPropagation() .
The following event modifiers can be used with v-on . Modifiers are directive postfixes denoted by a dot:
- .stop – stop event propagation
- .prevent – call event.preventDefault() to stop the default action of the event
- .capture – handle events targeting an inner element before handling events of the element that triggered the event
- .self – only trigger if event.target is the element itself
- .once – only run the event listener once
- .passive – opposite of calling event.preventDefault() . That is we want to let the default action run. .prevent and .passive shouldn’t be used together in one element.
For example, we can use the .prevent modifier to call event.preventDefault() instead of having to call the method in our event handler as follows:
index.js
:
new Vue({ el: "#app", data: { name: "" }, methods: { submit() { alert(this.name); } } });
index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <form v-on:submit.prevent="submit"> <label>Name</label> <input type="text" v-model="name" /> </form> </div> <script src="index.js"></script> </body> </html>
The order that they’re applied matters, so v-on:click.prevent.self
is different from v-on:click.self.prevent
Key Modifiers
We can also add key modifiers to listen to an event where specific keys are pressed.
Key names with multiple words should be written in kebab-case.
For instance, we can use key modifiers with v-on
as follows:
index.js
:
new Vue({ el: "#app", data: { name: "" }, methods: { submit() { alert(this.name); } } });
index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <input type="text" v-model="name" v-on:keyup.enter="submit" /> </div> <script src="index.js"></script> </body> </html>
Then when we press enter we’ll get an alert box with what we typed in.
We can show an alert box when the Page Down key is pressed instead:
index.js
:
new Vue({ el: "#app", data: { name: "" }, methods: { onPageDown() { alert(this.name); } } });
index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <input type="text" v-model="name" v-on:keyup.page-down="onPageDown" /> </div> <script src="index.js"></script> </body> </html>
Vue provides aliases for the most commonly used key codes for legacy browser support for the following keys:
.enter
- .tab
- .delete (captures both “Delete” and “Backspace” keys)
- .esc
- .space
- .up
- .down
.left
.right
If our app need to support IE9 then we should use the aliases since IE9’s key codes are different from other browsers for keys like .esc
and all arrow keys.
System Modifier Keys
Since Vue 2.1.0, it can also listen to key combinations that with the following system modifier keys:
.ctrl
.alt
.shift
.meta
The meta key is the command key on a Mac keyboard and Windows key on a Windows keyboard.
For example, we can use them as follows:
index.js
:
new Vue({ el: "#app", methods: { onCtrClick() { alert("Ctrl+Clicked"); } } });
index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>App</title> </head> <body> <div id="app"> <button v-on:click.ctrl="onCtrClick">Ctrl+Click Me</button> </div> <script src="index.js"></script> </body> </html>
Then when we Ctrl+Click on the button, we see Ctrl+Clicked
displayed in the alert box since onCtrlClick
is called.
Conclusion
We can listen to events with the v-on
directive. It takes various modifiers like click
to listen to click events, keyup
to listen to events when a key is released, etc.
We can also use it to listen to various key combination presses like v-on:click.ctrl
to listen to Ctrl + Click combinations.
Hello, may I translate your article into Chinese?I would like to share it with more developers in China. I will give the original author and original source.