4.2 Sensors – onKeyStroke
https://vueuse.org/onKeyStroke
作用
监听键盘按键是否被点击
官方示例
- 监听一个按键
import { onKeyStroke } from '@vueuse/core'
onKeyStroke('ArrowDown', (e) => {
e.preventDefault()
})
- 监听多个按键
import { onKeyStroke } from '@vueuse/core'
onKeyStroke(['s', 'S', 'ArrowDown'], (e) => {
e.preventDefault()
})
// listen to all keys by [true / skip the keyDefine]
onKeyStroke(true, (e) => {
e.preventDefault()
})
onKeyStroke((e) => {
e.preventDefault()
})
- 自定义事件目标
onKeyStroke('A', (e) => {
console.log('Key A pressed on document')
}, { target: document })
- 指令用法
vOnKeyStroke
,冒号后面是监听的按键,等号后面是回调方法。
<script setup lang="ts">
import { vOnKeyStroke } from '@vueuse/components'
function onUpdate(e: KeyboardEvent) {
// impl...
}
</script>
<template>
<input v-on-key-stroke:c,v="onUpdate" type="text">
<!-- with options -->
<input v-on-key-stroke:c,v="[onUpdate, { eventName: 'keyup' }]" type="text">
</template>
- 自定义键盘和简写
onKeyStroke('Shift', (e) => {
console.log('Shift key up')
}, { eventName: 'keyup' })
// 等价于
onKeyUp('Shift', () => console.log('Shift key up'))
// 这样的简写有三个
onKeyDown --> onKeyStroke(key, handler, {eventName: 'keydown'})
onKeyPressed --> onKeyStroke(key, handler, {eventName: 'keypress'})
onKeyUp --> onKeyStroke(key, handler, {eventName: 'keyup'})
源码分析
export function onKeyStroke(...args: any[]) {
let key: KeyFilter
let handler: (event: KeyboardEvent) => void
let options: OnKeyStrokeOptions = {}
/**
* 1 根据参数的个数,区分`key、handler、options`
*/
if (args.length === 3) {
key = args[0]
handler = args[1]
options = args[2]
}
else if (args.length === 2) {
if (typeof args[1] === 'object') {
key = true
handler = args[0]
options = args[1]
}
else {
key = args[0]
handler = args[1]
}
}
else {
key = true
handler = args[0]
}
const { target = defaultWindow, eventName = 'keydown', passive = false } = options
const predicate = createKeyPredicate(key)
const listener = (e: KeyboardEvent) => {
/**
* 3 当事件触发,检查这个事件e,在不在用户需要监控的范围内。如果在,触发handler回调
* predicate函数如下
*/
if (predicate(e))
handler(e)
}
/**
* 2 给window注册keydown事件的监听。如果触发,触发listener回调
*/
return useEventListener(target, eventName, listener, passive)
}
const createKeyPredicate = (keyFilter: KeyFilter): KeyPredicate => {
// 1 用户自定义了检查的函数
if (typeof keyFilter === 'function')
return keyFilter
// 2 用户传入了一个字符串,比如官方示例的'shift',则比较事件的key是不是等于'shift'
else if (typeof keyFilter === 'string')
return (event: KeyboardEvent) => event.key === keyFilter
// 3 用户传入了数组['s', 'S', 'ArrowDown'],则看数组中有没有事件的key
else if (Array.isArray(keyFilter))
return (event: KeyboardEvent) => keyFilter.includes(event.key)
// 4 用户传了true,或者不传,默认true
return () => true
}
onKeyDown \ onKeyUp
都是调用了onKeyStroke
,写死了一个参数
export function onKeyDown(key: KeyFilter, handler: (event: KeyboardEvent) => void, options: Omit<OnKeyStrokeOptions, 'eventName'> = {}) {
return onKeyStroke(key, handler, { ...options, eventName: 'keydown' })
}