chore: restore files unintentionally deleted in 6c61a4e
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
---
|
||||
title: System Modifier Keys Must Be Held During keyup Events
|
||||
impact: MEDIUM
|
||||
impactDescription: Modifier keys (ctrl, alt, shift, meta) behave differently with keyup - they must be held when the key is released
|
||||
type: gotcha
|
||||
tags: [vue3, events, keyboard, modifiers, keyup, shortcuts]
|
||||
---
|
||||
|
||||
# System Modifier Keys Must Be Held During keyup Events
|
||||
|
||||
**Impact: MEDIUM** - When using system modifier keys (`.ctrl`, `.alt`, `.shift`, `.meta`) with `keyup` events, the modifier must still be pressed when the other key is released. Releasing the modifier key first will not trigger the event, causing keyboard shortcuts to appear broken.
|
||||
|
||||
## Task Checklist
|
||||
|
||||
- [ ] Understand that `@keyup.ctrl` requires Ctrl to be held while releasing another key
|
||||
- [ ] Consider using `keydown` instead of `keyup` for modifier key combinations
|
||||
- [ ] Use `.exact` when you need precise modifier key control
|
||||
- [ ] Test keyboard shortcuts with proper key release order
|
||||
|
||||
**Incorrect:**
|
||||
```html
|
||||
<!-- WRONG: Expecting this to fire when Ctrl is released -->
|
||||
<template>
|
||||
<input @keyup.ctrl="onCtrlRelease" />
|
||||
<!-- This does NOT fire when you just release Ctrl! -->
|
||||
<!-- It fires when you release ANY key while holding Ctrl -->
|
||||
</template>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- WRONG: Misunderstanding keyup.ctrl behavior -->
|
||||
<template>
|
||||
<div @keyup.ctrl="handleShortcut">
|
||||
<!-- User presses Ctrl+S, releases Ctrl first, then S -->
|
||||
<!-- Event does NOT fire because Ctrl wasn't held during S release -->
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
```html
|
||||
<!-- CORRECT: User must hold Ctrl while releasing another key -->
|
||||
<template>
|
||||
<input @keyup.ctrl.s="saveDocument" />
|
||||
<!-- User presses Ctrl+S, then releases S while holding Ctrl -->
|
||||
<!-- Event fires correctly -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
function saveDocument(event) {
|
||||
event.preventDefault()
|
||||
// Save logic here
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- CORRECT: Use keydown for more intuitive modifier behavior -->
|
||||
<template>
|
||||
<div @keydown.ctrl.s="saveDocument">
|
||||
<!-- keydown fires immediately when both keys are pressed -->
|
||||
<!-- More intuitive for keyboard shortcuts -->
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- CORRECT: Use .exact for precise modifier control -->
|
||||
<template>
|
||||
<!-- Only fires when ONLY Ctrl is pressed (no Shift, Alt, etc.) -->
|
||||
<button @click.ctrl.exact="onCtrlClick">Ctrl+Click Only</button>
|
||||
|
||||
<!-- Fires with no system modifiers at all -->
|
||||
<button @click.exact="onPlainClick">Plain Click Only</button>
|
||||
</template>
|
||||
```
|
||||
|
||||
## How System Modifiers Work with keyup
|
||||
|
||||
```javascript
|
||||
// Timeline of Ctrl+S keydown:
|
||||
// 1. User presses Ctrl (keydown fires)
|
||||
// 2. User presses S while holding Ctrl (keydown fires)
|
||||
|
||||
// Timeline of Ctrl+S keyup:
|
||||
// 3. User releases S while holding Ctrl (keyup.ctrl.s fires!)
|
||||
// 4. User releases Ctrl (keyup fires, but not keyup.ctrl.s)
|
||||
|
||||
// Common mistake:
|
||||
// 3. User releases Ctrl first (nothing fires for our handler)
|
||||
// 4. User releases S (keyup.s fires, but not keyup.ctrl.s)
|
||||
```
|
||||
|
||||
## System Modifier Keys
|
||||
|
||||
```html
|
||||
<!-- Available system modifiers -->
|
||||
<input @keyup.ctrl="..." /> <!-- Ctrl key -->
|
||||
<input @keyup.alt="..." /> <!-- Alt key (Option on Mac) -->
|
||||
<input @keyup.shift="..." /> <!-- Shift key -->
|
||||
<input @keyup.meta="..." /> <!-- Cmd on Mac, Windows key on PC -->
|
||||
```
|
||||
|
||||
## The .exact Modifier
|
||||
|
||||
```html
|
||||
<!-- Different .exact behaviors -->
|
||||
|
||||
<!-- Fires even if Shift/Alt are also pressed -->
|
||||
<button @click.ctrl="onClick">Ctrl + any other modifiers</button>
|
||||
|
||||
<!-- Fires ONLY when Ctrl alone is pressed -->
|
||||
<button @click.ctrl.exact="onClick">Ctrl only, no other modifiers</button>
|
||||
|
||||
<!-- Fires ONLY when no system modifiers are pressed -->
|
||||
<button @click.exact="onClick">No modifiers allowed</button>
|
||||
```
|
||||
|
||||
## Best Practice: Prefer keydown for Shortcuts
|
||||
|
||||
```html
|
||||
<template>
|
||||
<div
|
||||
tabindex="0"
|
||||
@keydown.ctrl.s.prevent="save"
|
||||
@keydown.ctrl.z.prevent="undo"
|
||||
@keydown.ctrl.shift.z.prevent="redo"
|
||||
>
|
||||
<!-- keydown is more reliable for keyboard shortcuts -->
|
||||
<!-- Add .prevent to stop browser default (e.g., save dialog) -->
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Reference
|
||||
- [Vue.js Event Handling - Key Modifiers](https://vuejs.org/guide/essentials/event-handling.html#key-modifiers)
|
||||
- [Vue.js Event Handling - System Modifier Keys](https://vuejs.org/guide/essentials/event-handling.html#system-modifier-keys)
|
||||
Reference in New Issue
Block a user