vue 3 中 usekeyboardshortcut 封装快捷键监听,通过 onmounted/onunmounted 管理生命周期,支持组合键解析(如 "ctrl+s")、动态启停、多快捷键绑定及作用域限定。

在 Vue 3 的 setup 中封装键盘快捷键监听,核心是用 onMounted 和 onUnmounted 管理事件生命周期,并通过 ref 或 reactive 暴露状态和控制方法。关键在于避免重复绑定、支持组合键(如 Ctrl+S)、可动态启用/禁用,且不污染全局。
定义快捷键配置与匹配逻辑
快捷键本质是判断 event.key、event.ctrlKey、event.altKey、event.metaKey、event.shiftKey 的组合。建议把快捷键规则写成可读性高的字符串(如 "Ctrl+S"),再解析匹配:
- 统一转为小写处理,忽略大小写差异(
S和s都匹配) - 支持常见别名:
"Cmd"→metaKey(macOS),"Ctrl"→ctrlKey - 用
event.code更稳定(如"Enter"),但key更直观(如"s"),推荐优先用key,特殊场景(如防止输入法干扰)再切code
封装 useKeyboardShortcut 函数
返回一个响应式对象,含 isActive 控制开关、bind 手动绑定、unbind 清理,以及快捷键触发回调:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
import { onMounted, onUnmounted, ref, reactive } from 'vue'
export function useKeyboardShortcut() {
const isActive = ref(true)
const listeners = reactive(new Map())
const normalizeKey = (key) => key.toLowerCase()
const parseShortcut = (shortcut) => {
const parts = shortcut.split('+').map(s => s.trim())
return {
key: normalizeKey(parts.pop()),
ctrl: parts.includes('Ctrl') || parts.includes('Control'),
alt: parts.includes('Alt'),
shift: parts.includes('Shift'),
meta: parts.includes('Cmd') || parts.includes('Meta')
}
}
const matches = (e, config) => {
if (e.key.toLowerCase() !== config.key) return false
if (config.ctrl && !e.ctrlKey) return false
if (config.alt && !e.altKey) return false
if (config.shift && !e.shiftKey) return false
if (config.meta && !e.metaKey) return false
return true
}
const addListener = (shortcut, handler) => {
const config = parseShortcut(shortcut)
const listener = (e) => {
if (!isActive.value) return
if (matches(e, config)) {
e.preventDefault()
handler(e)
}
}
window.addEventListener('keydown', listener)
listeners.set(shortcut, { handler, listener })
}
const removeListener = (shortcut) => {
const entry = listeners.get(shortcut)
if (entry) {
window.removeEventListener('keydown', entry.listener)
listeners.delete(shortcut)
}
}
const bind = (shortcut, handler) => {
addListener(shortcut, handler)
}
const unbind = (shortcut) => {
removeListener(shortcut)
}
const clearAll = () => {
listeners.forEach((_, shortcut) => removeListener(shortcut))
}
onMounted(() => {
// 自动清理(可选)
})
onUnmounted(() => {
clearAll()
})
return {
isActive,
bind,
unbind,
clearAll
}
}
在组件中使用
直接解构调用,支持多个快捷键,也支持运行时启停:
import { defineComponent, onMounted } from 'vue'
import { useKeyboardShortcut } from './useKeyboardShortcut'
export default defineComponent({
setup() {
const { isActive, bind, unbind } = useKeyboardShortcut()
const onSave = () => console.log('保存触发')
const onUndo = () => console.log('撤销触发')
onMounted(() => {
bind('Ctrl+S', onSave)
bind('Ctrl+Z', onUndo)
// 支持 Cmd+S(macOS)
bind('Cmd+S', onSave)
})
const toggleShortcut = () => {
isActive.value = !isActive.value
}
return () => (
<div>
<button onclick="{toggleShortcut}">
{isActive.value ? '禁用快捷键' : '启用快捷键'}
</button>
</div>
)
}
})
进阶建议:支持作用域与防抖
若需限定快捷键只在某元素聚焦时生效(如仅编辑器内响应 Ctrl+S),可传入 targetRef,监听该元素的 keydown 而非 window;高频快捷键(如实时搜索)可加 useThrottleFn 包裹 handler,避免连按触发多次。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










