From d74b8beabceb86ad8d09c20bfb0bd955ce8e976d Mon Sep 17 00:00:00 2001 From: ntepluhina Date: Mon, 13 Jan 2020 17:15:50 +0200 Subject: [PATCH 1/5] Moved events handling up to modifiers --- src/.vuepress/components/events-1.vue | 16 ++ src/.vuepress/components/events-2.vue | 23 ++ src/.vuepress/components/events-3.vue | 16 ++ src/.vuepress/config.js | 20 +- src/guide/events.md | 293 ++++++++++++++++++++++++++ 5 files changed, 366 insertions(+), 2 deletions(-) create mode 100644 src/.vuepress/components/events-1.vue create mode 100644 src/.vuepress/components/events-2.vue create mode 100644 src/.vuepress/components/events-3.vue create mode 100644 src/guide/events.md diff --git a/src/.vuepress/components/events-1.vue b/src/.vuepress/components/events-1.vue new file mode 100644 index 0000000000..1db5aaf4a3 --- /dev/null +++ b/src/.vuepress/components/events-1.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/.vuepress/components/events-2.vue b/src/.vuepress/components/events-2.vue new file mode 100644 index 0000000000..300812de2a --- /dev/null +++ b/src/.vuepress/components/events-2.vue @@ -0,0 +1,23 @@ + + + diff --git a/src/.vuepress/components/events-3.vue b/src/.vuepress/components/events-3.vue new file mode 100644 index 0000000000..6784ffafa8 --- /dev/null +++ b/src/.vuepress/components/events-3.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index e6feb5592e..0845191cda 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -25,7 +25,23 @@ module.exports = { ], sidebarDepth: 2, sidebar: { - '/guide/': ['installation', 'introduction', 'instance', 'template-syntax'] + '/guide/': [ + { + title: 'Essentials', + collapsable: true, + children: [ + 'installation', + 'introduction', + 'instance', + 'template-syntax', + // 'computed', + // 'class-and-style', + // 'conditional', + // 'list' + 'events' + ] + } + ] } }, plugins: { @@ -39,4 +55,4 @@ module.exports = { } } } -}; +} diff --git a/src/guide/events.md b/src/guide/events.md new file mode 100644 index 0000000000..805ec88997 --- /dev/null +++ b/src/guide/events.md @@ -0,0 +1,293 @@ +# Event Handling + +
Learn how to handle events in a free Vue School lesson
+ +## Listening to Events + +We can use the `v-on` directive to listen to DOM events and run some JavaScript when they're triggered. + +For example: + +```html +
+ +

The button above has been clicked {{ counter }} times.

+
+``` + +```js +Vue.createApp().mount( + { + data() { + return { + counter: 1 + } + } + }, + '#example-1' +) +``` + +Result: + + + +## Method Event Handlers + +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. + +For example: + +```html +
+ + +
+``` + +```js +Vue.createApp().mount( + { + data() { + return { + name: 'Vue.js' + } + }, + methods: { + greet(event) { + // `this` inside methods points to the Vue instance + alert('Hello ' + this.name + '!') + // `event` is the native DOM event + if (event) { + alert(event.target.tagName) + } + } + } + }, + '#example-2' +) +``` + +Result: + + + +## Methods in Inline Handlers + +Instead of binding directly to a method name, we can also use methods in an inline JavaScript statement: + +```html +
+ + +
+``` + +```js +Vue.createApp().mount( + { + methods: { + say(message) { + alert(message) + } + } + }, + '#example-3' +) +``` + +Result: + + + +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: + +```html + +``` + +```js +// ... +methods: { + warn(message, event) { + // now we have access to the native event + if (event) { + event.preventDefault() + } + alert(message) + } +} +``` + +## Event Modifiers + +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. + +To address this problem, Vue provides **event modifiers** for `v-on`. Recall that modifiers are directive postfixes denoted by a dot. + +- `.stop` +- `.prevent` +- `.capture` +- `.self` +- `.once` +- `.passive` + +```html + + + + +
+ + + + + +
+ + + +
...
+ + + +
...
+``` + +

Order matters when using modifiers because the relevant code is generated in the same order. Therefore using `v-on:click.prevent.self` will prevent **all clicks** while `v-on:click.self.prevent` will only prevent clicks on the element itself.

+ +> New in 2.1.4+ + +```html + + +``` + +Unlike the other modifiers, which are exclusive to native DOM events, the `.once` modifier can also be used on [component events](components-custom-events.html). If you haven't read about components yet, don't worry about this for now. + +> New in 2.3.0+ + +Vue also offers the `.passive` modifier, corresponding to [`addEventListener`'s `passive` option](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters). + +```html + + + +
...
+``` + +The `.passive` modifier is especially useful for improving performance on mobile devices. + +

Don't use `.passive` and `.prevent` together, because `.prevent` will be ignored and your browser will probably show you a warning. Remember, `.passive` communicates to the browser that you _don't_ want to prevent the event's default behavior.

+ +## Key Modifiers + +When listening for keyboard events, we often need to check for specific keys. Vue allows adding key modifiers for `v-on` when listening for key events: + +```html + + +``` + +You can directly use any valid key names exposed via [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values) as modifiers by converting them to kebab-case. + +```html + +``` + +In the above example, the handler will only be called if `$event.key` is equal to `'PageDown'`. + +### Key Codes + +

The use of `keyCode` events [is deprecated](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) and may not be supported in new browsers.

+ +Using `keyCode` attributes is also permitted: + +```html + +``` + +Vue provides aliases for the most commonly used key codes when necessary for legacy browser support: + +- `.enter` +- `.tab` +- `.delete` (captures both "Delete" and "Backspace" keys) +- `.esc` +- `.space` +- `.up` +- `.down` +- `.left` +- `.right` + +

A few keys (`.esc` and all arrow keys) have inconsistent `key` values in IE9, so these built-in aliases should be preferred if you need to support IE9.

+ +You can also [define custom key modifier aliases](../api/#keyCodes) via the global `config.keyCodes` object: + +```js +// enable `v-on:keyup.f1` +Vue.config.keyCodes.f1 = 112 +``` + +## System Modifier Keys + +> New in 2.1.0+ + +You can use the following modifiers to trigger mouse or keyboard event listeners only when the corresponding modifier key is pressed: + +- `.ctrl` +- `.alt` +- `.shift` +- `.meta` + +> Note: On Macintosh keyboards, meta is the command key (⌘). On Windows keyboards, meta is the Windows key (⊞). On Sun Microsystems keyboards, meta is marked as a solid diamond (◆). On certain keyboards, specifically MIT and Lisp machine keyboards and successors, such as the Knight keyboard, space-cadet keyboard, meta is labeled “META”. On Symbolics keyboards, meta is labeled “META” or “Meta”. + +For example: + +```html + + + + +
Do something
+``` + +

Note that modifier keys are different from regular keys and when used with `keyup` events, they have to be pressed when the event is emitted. In other words, `keyup.ctrl` will only trigger if you release a key while holding down `ctrl`. It won't trigger if you release the `ctrl` key alone. If you do want such behaviour, use the `keyCode` for `ctrl` instead: `keyup.17`.

+ +### `.exact` Modifier + +> New in 2.5.0+ + +The `.exact` modifier allows control of the exact combination of system modifiers needed to trigger an event. + +```html + + + + + + + + +``` + +### Mouse Button Modifiers + +> New in 2.2.0+ + +- `.left` +- `.right` +- `.middle` + +These modifiers restrict the handler to events triggered by a specific mouse button. + +## Why Listeners in HTML? + +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`: + +1. It's easier to locate the handler function implementations within your JS code by skimming the HTML template. + +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. + +3. When a ViewModel is destroyed, all event listeners are automatically removed. You don't need to worry about cleaning it up yourself. From efaa6d3f0543931fadf19b640f8f6a051261b95a Mon Sep 17 00:00:00 2001 From: ntepluhina Date: Mon, 13 Jan 2020 17:23:54 +0200 Subject: [PATCH 2/5] Moved the rest of event handling --- src/guide/events.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/guide/events.md b/src/guide/events.md index 805ec88997..f421d8ef08 100644 --- a/src/guide/events.md +++ b/src/guide/events.md @@ -156,18 +156,16 @@ To address this problem, Vue provides **event modifiers** for `v-on`. Recall tha
...
``` -

Order matters when using modifiers because the relevant code is generated in the same order. Therefore using `v-on:click.prevent.self` will prevent **all clicks** while `v-on:click.self.prevent` will only prevent clicks on the element itself.

- -> New in 2.1.4+ +::: tip +Order matters when using modifiers because the relevant code is generated in the same order. Therefore using `v-on:click.prevent.self` will prevent **all clicks** while `v-on:click.self.prevent` will only prevent clicks on the element itself. +::: ```html ``` -Unlike the other modifiers, which are exclusive to native DOM events, the `.once` modifier can also be used on [component events](components-custom-events.html). If you haven't read about components yet, don't worry about this for now. - -> New in 2.3.0+ +Unlike the other modifiers, which are exclusive to native DOM events, the `.once` modifier can also be used on [component events](TODO:components-custom-events.html). If you haven't read about components yet, don't worry about this for now. Vue also offers the `.passive` modifier, corresponding to [`addEventListener`'s `passive` option](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters). @@ -180,7 +178,9 @@ Vue also offers the `.passive` modifier, corresponding to [`addEventListener`'s The `.passive` modifier is especially useful for improving performance on mobile devices. -

Don't use `.passive` and `.prevent` together, because `.prevent` will be ignored and your browser will probably show you a warning. Remember, `.passive` communicates to the browser that you _don't_ want to prevent the event's default behavior.

+::: tip +Don't use `.passive` and `.prevent` together, because `.prevent` will be ignored and your browser will probably show you a warning. Remember, `.passive` communicates to the browser that you _don't_ want to prevent the event's default behavior. +::: ## Key Modifiers @@ -201,7 +201,9 @@ In the above example, the handler will only be called if `$event.key` is equal t ### Key Codes -

The use of `keyCode` events [is deprecated](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) and may not be supported in new browsers.

+::: tip +The use of `keyCode` events [is deprecated](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) and may not be supported in new browsers. +::: Using `keyCode` attributes is also permitted: @@ -221,9 +223,9 @@ Vue provides aliases for the most commonly used key codes when necessary for leg - `.left` - `.right` -

A few keys (`.esc` and all arrow keys) have inconsistent `key` values in IE9, so these built-in aliases should be preferred if you need to support IE9.

+A few keys (`.esc` and all arrow keys) have inconsistent `key` values in IE9, so these built-in aliases should be preferred if you need to support IE9. -You can also [define custom key modifier aliases](../api/#keyCodes) via the global `config.keyCodes` object: +You can also [define custom key modifier aliases](TODO:../api/#keyCodes) via the global `config.keyCodes` object: ```js // enable `v-on:keyup.f1` @@ -232,8 +234,6 @@ Vue.config.keyCodes.f1 = 112 ## System Modifier Keys -> New in 2.1.0+ - You can use the following modifiers to trigger mouse or keyboard event listeners only when the corresponding modifier key is pressed: - `.ctrl` @@ -241,7 +241,9 @@ You can use the following modifiers to trigger mouse or keyboard event listeners - `.shift` - `.meta` -> Note: On Macintosh keyboards, meta is the command key (⌘). On Windows keyboards, meta is the Windows key (⊞). On Sun Microsystems keyboards, meta is marked as a solid diamond (◆). On certain keyboards, specifically MIT and Lisp machine keyboards and successors, such as the Knight keyboard, space-cadet keyboard, meta is labeled “META”. On Symbolics keyboards, meta is labeled “META” or “Meta”. +::: tip Note +On Macintosh keyboards, meta is the command key (⌘). On Windows keyboards, meta is the Windows key (⊞). On Sun Microsystems keyboards, meta is marked as a solid diamond (◆). On certain keyboards, specifically MIT and Lisp machine keyboards and successors, such as the Knight keyboard, space-cadet keyboard, meta is labeled “META”. On Symbolics keyboards, meta is labeled “META” or “Meta”. +::: For example: @@ -253,12 +255,12 @@ For example:
Do something
``` -

Note that modifier keys are different from regular keys and when used with `keyup` events, they have to be pressed when the event is emitted. In other words, `keyup.ctrl` will only trigger if you release a key while holding down `ctrl`. It won't trigger if you release the `ctrl` key alone. If you do want such behaviour, use the `keyCode` for `ctrl` instead: `keyup.17`.

+::: tip Tip +Note that modifier keys are different from regular keys and when used with `keyup` events, they have to be pressed when the event is emitted. In other words, `keyup.ctrl` will only trigger if you release a key while holding down `ctrl`. It won't trigger if you release the `ctrl` key alone. If you do want such behaviour, use the `keyCode` for `ctrl` instead: `keyup.17`. +::: ### `.exact` Modifier -> New in 2.5.0+ - The `.exact` modifier allows control of the exact combination of system modifiers needed to trigger an event. ```html @@ -274,8 +276,6 @@ The `.exact` modifier allows control of the exact combination of system modifier ### Mouse Button Modifiers -> New in 2.2.0+ - - `.left` - `.right` - `.middle` From 6404403c72e8f7b61dd52e68bce760cbf0f33a3a Mon Sep 17 00:00:00 2001 From: ntepluhina Date: Wed, 22 Jan 2020 20:02:40 +0200 Subject: [PATCH 3/5] fix: added missing comma --- src/.vuepress/config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index 39ff1e14af..b6f858f2b6 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -37,8 +37,8 @@ module.exports = { // 'computed', // 'class-and-style', 'conditional', - 'list' - 'events' + 'list', + 'events', 'conditional', 'list' ] From e1880152c6cadd99e7f782dac11f9251461e40d7 Mon Sep 17 00:00:00 2001 From: ntepluhina Date: Wed, 22 Jan 2020 20:02:59 +0200 Subject: [PATCH 4/5] fix: fixed order --- src/.vuepress/config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index b6f858f2b6..e9f18be805 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -39,8 +39,6 @@ module.exports = { 'conditional', 'list', 'events', - 'conditional', - 'list' ] } ] From 4a46dc8f81d55d3970abad31a0212d03c3c7e389 Mon Sep 17 00:00:00 2001 From: ntepluhina Date: Wed, 22 Jan 2020 20:03:26 +0200 Subject: [PATCH 5/5] fix: uncommented computed --- src/.vuepress/config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index e9f18be805..a573349d1f 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -34,8 +34,8 @@ module.exports = { 'introduction', 'instance', 'template-syntax', - // 'computed', - // 'class-and-style', + 'computed', + 'class-and-style', 'conditional', 'list', 'events',