Skip to content

Commit 5693838

Browse files
committed
event handling
1 parent a879460 commit 5693838

File tree

1 file changed

+141
-62
lines changed

1 file changed

+141
-62
lines changed

src/guide/essentials/event-handling.md

Lines changed: 141 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
aside: deep
3+
---
4+
15
# Event Handling
26

37
## Listening to Events
@@ -6,88 +10,140 @@ We can use the `v-on` directive, which we typically shorten to the `@` symbol, t
610

711
For example:
812

9-
```vue-html
10-
<div id="basic-event">
11-
<button @click="counter += 1">Add 1</button>
12-
<p>The button above has been clicked {{ counter }} times.</p>
13-
</div>
13+
<div class="composition-api">
14+
15+
```js
16+
const counter = ref(0)
1417
```
1518

19+
</div>
20+
<div class="options-api">
21+
1622
```js
17-
Vue.createApp({
18-
data() {
19-
return {
20-
counter: 0
21-
}
23+
data() {
24+
return {
25+
counter: 0
2226
}
23-
}).mount('#basic-event')
27+
}
2428
```
2529

26-
Result:
30+
</div>
2731

28-
<!-- <common-codepen-snippet title="Event handling: basic" slug="xxGadPZ" tab="result" :preview="false" /> -->
32+
```vue-html
33+
<button @click="counter++">Add 1</button>
34+
<p>The button above has been clicked {{ counter }} times.</p>
35+
```
36+
37+
<div class="composition-api">
38+
39+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgY291bnRlciA9IHJlZigwKVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cblx0PGJ1dHRvbiBAY2xpY2s9XCJjb3VudGVyKytcIj5BZGQgMTwvYnV0dG9uPlxuXHQ8cD5UaGUgYnV0dG9uIGFib3ZlIGhhcyBiZWVuIGNsaWNrZWQge3sgY291bnRlciB9fSB0aW1lcy48L3A+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
40+
41+
</div>
42+
<div class="options-api">
43+
44+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcblx0ICByZXR1cm4ge1xuICAgIFx0Y291bnRlcjogMFxuICBcdH1cblx0fVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cblx0PGJ1dHRvbiBAY2xpY2s9XCJjb3VudGVyKytcIj5BZGQgMTwvYnV0dG9uPlxuXHQ8cD5UaGUgYnV0dG9uIGFib3ZlIGhhcyBiZWVuIGNsaWNrZWQge3sgY291bnRlciB9fSB0aW1lcy48L3A+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
45+
46+
</div>
2947

3048
## Method Event Handlers
3149

3250
The logic for many event handlers will be more complex though, so keeping your JavaScript in the value of the `v-on` attribute isn't feasible. That's why `v-on` can also accept the name of a method you'd like to call.
3351

3452
For example:
3553

36-
```vue-html
37-
<div id="event-with-method">
38-
<!-- `greet` is the name of a method defined below -->
39-
<button @click="greet">Greet</button>
40-
</div>
54+
<div class="composition-api">
55+
56+
```js
57+
const name = ref('Vue.js')
58+
59+
function greet(event) {
60+
alert(`Hello ${name.value}!`)
61+
// `event` is the native DOM event
62+
if (event) {
63+
alert(event.target.tagName)
64+
}
65+
}
4166
```
4267

68+
</div>
69+
<div class="options-api">
70+
4371
```js
44-
Vue.createApp({
45-
data() {
46-
return {
47-
name: 'Vue.js'
48-
}
49-
},
50-
methods: {
51-
greet(event) {
52-
// `this` inside methods points to the current active instance
53-
alert('Hello ' + this.name + '!')
54-
// `event` is the native DOM event
55-
if (event) {
56-
alert(event.target.tagName)
57-
}
72+
data() {
73+
return {
74+
name: 'Vue.js'
75+
}
76+
},
77+
methods: {
78+
greet(event) {
79+
// `this` inside methods points to the current active instance
80+
alert(`Hello ${this.name}!`)
81+
// `event` is the native DOM event
82+
if (event) {
83+
alert(event.target.tagName)
5884
}
5985
}
60-
}).mount('#event-with-method')
86+
}
6187
```
6288

63-
Result:
89+
</div>
6490

65-
<!-- <common-codepen-snippet title="Event handling: with a method" slug="jOPvmaX" tab="result" :preview="false" /> -->
91+
```vue-html
92+
<!-- `greet` is the name of a method defined below -->
93+
<button @click="greet">Greet</button>
94+
```
95+
96+
<div class="composition-api">
97+
98+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgbmFtZSA9IHJlZignVnVlLmpzJylcblxuZnVuY3Rpb24gZ3JlZXQoZXZlbnQpIHtcbiAgYWxlcnQoYEhlbGxvICR7bmFtZS52YWx1ZX0hYClcbiAgLy8gYGV2ZW50YCBpcyB0aGUgbmF0aXZlIERPTSBldmVudFxuICBpZiAoZXZlbnQpIHtcbiAgICBhbGVydChldmVudC50YXJnZXQudGFnTmFtZSlcbiAgfVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cblx0PGJ1dHRvbiBAY2xpY2s9XCJncmVldFwiPkdyZWV0PC9idXR0b24+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
99+
100+
</div>
101+
<div class="options-api">
102+
103+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogJ1Z1ZS5qcydcbiAgICB9XG4gIH0sXG4gIG1ldGhvZHM6IHtcbiAgICBncmVldChldmVudCkge1xuICAgICAgLy8gYHRoaXNgIGluc2lkZSBtZXRob2RzIHBvaW50cyB0byB0aGUgY3VycmVudCBhY3RpdmUgaW5zdGFuY2VcbiAgICAgIGFsZXJ0KGBIZWxsbyAke3RoaXMubmFtZX0hYClcbiAgICAgIC8vIGBldmVudGAgaXMgdGhlIG5hdGl2ZSBET00gZXZlbnRcbiAgICAgIGlmIChldmVudCkge1xuICAgICAgICBhbGVydChldmVudC50YXJnZXQudGFnTmFtZSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG5cdDxidXR0b24gQGNsaWNrPVwiZ3JlZXRcIj5HcmVldDwvYnV0dG9uPlxuPC90ZW1wbGF0ZT4iLCJpbXBvcnQtbWFwLmpzb24iOiJ7XG4gIFwiaW1wb3J0c1wiOiB7XG4gICAgXCJ2dWVcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvdnVlLnJ1bnRpbWUuZXNtLWJyb3dzZXIuanNcIlxuICB9XG59In0=)
104+
105+
</div>
66106

67107
## Methods in Inline Handlers
68108

69109
Instead of binding directly to a method name, we can also use methods in an inline JavaScript statement:
70110

71-
```vue-html
72-
<div id="inline-handler">
73-
<button @click="say('hi')">Say hi</button>
74-
<button @click="say('what')">Say what</button>
75-
</div>
111+
<div class="composition-api">
112+
113+
```js
114+
function say(message) {
115+
alert(message)
116+
}
76117
```
77118

119+
</div>
120+
<div class="options-api">
121+
78122
```js
79-
Vue.createApp({
80-
methods: {
81-
say(message) {
82-
alert(message)
83-
}
123+
methods: {
124+
say(message) {
125+
alert(message)
84126
}
85-
}).mount('#inline-handler')
127+
}
86128
```
87129

88-
Result:
130+
</div>
89131

90-
<!-- <common-codepen-snippet title="Event handling: with an inline handler" slug="WNvgjda" tab="result" :preview="false" /> -->
132+
```vue-html
133+
<button @click="say('hi')">Say hi</button>
134+
<button @click="say('what')">Say what</button>
135+
```
136+
137+
<div class="composition-api">
138+
139+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmZ1bmN0aW9uIHNheShtZXNzYWdlKSB7XG4gIGFsZXJ0KG1lc3NhZ2UpXG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuXHQ8YnV0dG9uIEBjbGljaz1cInNheSgnaGknKVwiPlNheSBoaTwvYnV0dG9uPlxuICA8YnV0dG9uIEBjbGljaz1cInNheSgnd2hhdCcpXCI+U2F5IHdoYXQ8L2J1dHRvbj5cbjwvdGVtcGxhdGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCJcbiAgfVxufSJ9)
140+
141+
</div>
142+
<div class="options-api">
143+
144+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbWV0aG9kczoge1xuXHQgIHNheShtZXNzYWdlKSB7XG4gICAgXHRhbGVydChtZXNzYWdlKVxuICBcdH1cblx0fVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cblx0PGJ1dHRvbiBAY2xpY2s9XCJzYXkoJ2hpJylcIj5TYXkgaGk8L2J1dHRvbj5cbiAgPGJ1dHRvbiBAY2xpY2s9XCJzYXkoJ3doYXQnKVwiPlNheSB3aGF0PC9idXR0b24+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
145+
146+
</div>
91147

92148
Sometimes we also need to access the original DOM event in an inline statement handler. You can pass it into a method using the special `$event` variable:
93149

@@ -97,8 +153,22 @@ Sometimes we also need to access the original DOM event in an inline statement h
97153
</button>
98154
```
99155

156+
<div class="composition-api">
157+
158+
```js
159+
function warn(message, event) {
160+
// `now we have access to the native event`
161+
if (event) {
162+
event.preventDefault()
163+
}
164+
alert(message)
165+
}
166+
```
167+
168+
</div>
169+
<div class="options-api">
170+
100171
```js
101-
// ...
102172
methods: {
103173
warn(message, event) {
104174
// now we have access to the native event
@@ -110,6 +180,8 @@ methods: {
110180
}
111181
```
112182

183+
</div>
184+
113185
## Multiple Event Handlers
114186

115187
You can have multiple methods in an event handler separated by a comma operator like this:
@@ -121,8 +193,23 @@ You can have multiple methods in an event handler separated by a comma operator
121193
</button>
122194
```
123195

196+
<div class="composition-api">
197+
198+
```js
199+
function one(event) {
200+
// first handler logic...
201+
}
202+
203+
function two(event) {
204+
// second handler logic...
205+
}
206+
```
207+
208+
</div>
209+
<div class="options-api">
210+
211+
124212
```js
125-
// ...
126213
methods: {
127214
one(event) {
128215
// first handler logic...
@@ -133,6 +220,8 @@ methods: {
133220
}
134221
```
135222

223+
</div>
224+
136225
## Event Modifiers
137226

138227
It is a very common need to call `event.preventDefault()` or `event.stopPropagation()` inside event handlers. Although we can do this easily inside methods, it would be better if the methods can be purely about data logic rather than having to deal with DOM event details.
@@ -225,7 +314,7 @@ Vue provides aliases for the most commonly used keys:
225314
- `.left`
226315
- `.right`
227316

228-
## System Modifier Keys
317+
### System Modifier Keys
229318

230319
You can use the following modifiers to trigger mouse or keyboard event listeners only when the corresponding modifier key is pressed:
231320

@@ -267,20 +356,10 @@ The `.exact` modifier allows control of the exact combination of system modifier
267356
<button @click.exact="onClick">A</button>
268357
```
269358

270-
### Mouse Button Modifiers
359+
## Mouse Button Modifiers
271360

272361
- `.left`
273362
- `.right`
274363
- `.middle`
275364

276365
These modifiers restrict the handler to events triggered by a specific mouse button.
277-
278-
## Why Listeners in HTML?
279-
280-
You might be concerned that this whole event listening approach violates the good old rules about "separation of concerns". Rest assured - since all Vue handler functions and expressions are strictly bound to the ViewModel that's handling the current view, it won't cause any maintenance difficulty. In fact, there are several benefits in using `v-on` or `@`:
281-
282-
1. It's easier to locate the handler function implementations within your JS code by skimming the HTML template.
283-
284-
2. Since you don't have to manually attach event listeners in JS, your ViewModel code can be pure logic and DOM-free. This makes it easier to test.
285-
286-
3. When a ViewModel is destroyed, all event listeners are automatically removed. You don't need to worry about cleaning it up yourself.

0 commit comments

Comments
 (0)