You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<p>The button above has been clicked {{ counter }} times.</p>
35
+
```
36
+
37
+
<divclass="composition-api">
38
+
39
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgY291bnRlciA9IHJlZigwKVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cblx0PGJ1dHRvbiBAY2xpY2s9XCJjb3VudGVyKytcIj5BZGQgMTwvYnV0dG9uPlxuXHQ8cD5UaGUgYnV0dG9uIGFib3ZlIGhhcyBiZWVuIGNsaWNrZWQge3sgY291bnRlciB9fSB0aW1lcy48L3A+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
40
+
41
+
</div>
42
+
<divclass="options-api">
43
+
44
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcblx0ICByZXR1cm4ge1xuICAgIFx0Y291bnRlcjogMFxuICBcdH1cblx0fVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cblx0PGJ1dHRvbiBAY2xpY2s9XCJjb3VudGVyKytcIj5BZGQgMTwvYnV0dG9uPlxuXHQ8cD5UaGUgYnV0dG9uIGFib3ZlIGhhcyBiZWVuIGNsaWNrZWQge3sgY291bnRlciB9fSB0aW1lcy48L3A+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
45
+
46
+
</div>
29
47
30
48
## Method Event Handlers
31
49
32
50
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.
33
51
34
52
For example:
35
53
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
+
<divclass="composition-api">
55
+
56
+
```js
57
+
constname=ref('Vue.js')
58
+
59
+
functiongreet(event) {
60
+
alert(`Hello ${name.value}!`)
61
+
// `event` is the native DOM event
62
+
if (event) {
63
+
alert(event.target.tagName)
64
+
}
65
+
}
41
66
```
42
67
68
+
</div>
69
+
<divclass="options-api">
70
+
43
71
```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)
58
84
}
59
85
}
60
-
}).mount('#event-with-method')
86
+
}
61
87
```
62
88
63
-
Result:
89
+
</div>
64
90
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
+
<divclass="composition-api">
97
+
98
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgbmFtZSA9IHJlZignVnVlLmpzJylcblxuZnVuY3Rpb24gZ3JlZXQoZXZlbnQpIHtcbiAgYWxlcnQoYEhlbGxvICR7bmFtZS52YWx1ZX0hYClcbiAgLy8gYGV2ZW50YCBpcyB0aGUgbmF0aXZlIERPTSBldmVudFxuICBpZiAoZXZlbnQpIHtcbiAgICBhbGVydChldmVudC50YXJnZXQudGFnTmFtZSlcbiAgfVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cblx0PGJ1dHRvbiBAY2xpY2s9XCJncmVldFwiPkdyZWV0PC9idXR0b24+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
99
+
100
+
</div>
101
+
<divclass="options-api">
102
+
103
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogJ1Z1ZS5qcydcbiAgICB9XG4gIH0sXG4gIG1ldGhvZHM6IHtcbiAgICBncmVldChldmVudCkge1xuICAgICAgLy8gYHRoaXNgIGluc2lkZSBtZXRob2RzIHBvaW50cyB0byB0aGUgY3VycmVudCBhY3RpdmUgaW5zdGFuY2VcbiAgICAgIGFsZXJ0KGBIZWxsbyAke3RoaXMubmFtZX0hYClcbiAgICAgIC8vIGBldmVudGAgaXMgdGhlIG5hdGl2ZSBET00gZXZlbnRcbiAgICAgIGlmIChldmVudCkge1xuICAgICAgICBhbGVydChldmVudC50YXJnZXQudGFnTmFtZSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG5cdDxidXR0b24gQGNsaWNrPVwiZ3JlZXRcIj5HcmVldDwvYnV0dG9uPlxuPC90ZW1wbGF0ZT4iLCJpbXBvcnQtbWFwLmpzb24iOiJ7XG4gIFwiaW1wb3J0c1wiOiB7XG4gICAgXCJ2dWVcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvdnVlLnJ1bnRpbWUuZXNtLWJyb3dzZXIuanNcIlxuICB9XG59In0=)
104
+
105
+
</div>
66
106
67
107
## Methods in Inline Handlers
68
108
69
109
Instead of binding directly to a method name, we can also use methods in an inline JavaScript statement:
70
110
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
+
<divclass="composition-api">
112
+
113
+
```js
114
+
functionsay(message) {
115
+
alert(message)
116
+
}
76
117
```
77
118
119
+
</div>
120
+
<divclass="options-api">
121
+
78
122
```js
79
-
Vue.createApp({
80
-
methods: {
81
-
say(message) {
82
-
alert(message)
83
-
}
123
+
methods: {
124
+
say(message) {
125
+
alert(message)
84
126
}
85
-
}).mount('#inline-handler')
127
+
}
86
128
```
87
129
88
-
Result:
130
+
</div>
89
131
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
+
<divclass="composition-api">
138
+
139
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmZ1bmN0aW9uIHNheShtZXNzYWdlKSB7XG4gIGFsZXJ0KG1lc3NhZ2UpXG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuXHQ8YnV0dG9uIEBjbGljaz1cInNheSgnaGknKVwiPlNheSBoaTwvYnV0dG9uPlxuICA8YnV0dG9uIEBjbGljaz1cInNheSgnd2hhdCcpXCI+U2F5IHdoYXQ8L2J1dHRvbj5cbjwvdGVtcGxhdGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCJcbiAgfVxufSJ9)
140
+
141
+
</div>
142
+
<divclass="options-api">
143
+
144
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbWV0aG9kczoge1xuXHQgIHNheShtZXNzYWdlKSB7XG4gICAgXHRhbGVydChtZXNzYWdlKVxuICBcdH1cblx0fVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cblx0PGJ1dHRvbiBAY2xpY2s9XCJzYXkoJ2hpJylcIj5TYXkgaGk8L2J1dHRvbj5cbiAgPGJ1dHRvbiBAY2xpY2s9XCJzYXkoJ3doYXQnKVwiPlNheSB3aGF0PC9idXR0b24+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
145
+
146
+
</div>
91
147
92
148
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:
93
149
@@ -97,8 +153,22 @@ Sometimes we also need to access the original DOM event in an inline statement h
97
153
</button>
98
154
```
99
155
156
+
<divclass="composition-api">
157
+
158
+
```js
159
+
functionwarn(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
+
<divclass="options-api">
170
+
100
171
```js
101
-
// ...
102
172
methods: {
103
173
warn(message, event) {
104
174
// now we have access to the native event
@@ -110,6 +180,8 @@ methods: {
110
180
}
111
181
```
112
182
183
+
</div>
184
+
113
185
## Multiple Event Handlers
114
186
115
187
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
121
193
</button>
122
194
```
123
195
196
+
<divclass="composition-api">
197
+
198
+
```js
199
+
functionone(event) {
200
+
// first handler logic...
201
+
}
202
+
203
+
functiontwo(event) {
204
+
// second handler logic...
205
+
}
206
+
```
207
+
208
+
</div>
209
+
<divclass="options-api">
210
+
211
+
124
212
```js
125
-
// ...
126
213
methods: {
127
214
one(event) {
128
215
// first handler logic...
@@ -133,6 +220,8 @@ methods: {
133
220
}
134
221
```
135
222
223
+
</div>
224
+
136
225
## Event Modifiers
137
226
138
227
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:
225
314
-`.left`
226
315
-`.right`
227
316
228
-
## System Modifier Keys
317
+
###System Modifier Keys
229
318
230
319
You can use the following modifiers to trigger mouse or keyboard event listeners only when the corresponding modifier key is pressed:
231
320
@@ -267,20 +356,10 @@ The `.exact` modifier allows control of the exact combination of system modifier
267
356
<button @click.exact="onClick">A</button>
268
357
```
269
358
270
-
###Mouse Button Modifiers
359
+
## Mouse Button Modifiers
271
360
272
361
-`.left`
273
362
-`.right`
274
363
-`.middle`
275
364
276
365
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