接到一个需求:点击页面连接时按住 Ctrl
按键则以新窗口形式打开该连接,原页面不进行跳转,这个需求比较棒,它保证了页面跳转时的灵活性。html
这个需求实现的重点是在何处添加判断是否以新窗口打开
的代码,好比在每一个连接点击的地方加入逻辑判断,这是最差的实现,由于这种方法改动点很大,并且没法自动兼容新连接的添加。而后可能想到的是拦截 $router.push
行为,或者封装一个自定义指令,再在合适的地方添加指令,这些都是否是很好的实现方式,咱们应该考虑如何以最小的改动而且向后兼容,那就是在 全局的 beforeEach 路由守卫
中添加逻辑。vue
咱们须要维护一个记载当前按键的数据,用来帮助咱们判断 Ctrl
键是否按下。markdown
首先咱们在项目中维护公共函数的地方新建一个 keyboard.js
文件。函数
const keys = {}
export function addKeyboardKey (e) {
// 别用已经废弃的 keycode 字段
keys[e.key] = true
}
export function removeKeyboardKey (e) {
delete keys[e.key]
}
export function isCtrlPress(e) {
return keys['Control']
}
复制代码
而后寻找一个合适的地方添加键盘的事件监听,好比在 App.vue
的 created
中。oop
// 下面只展现需求相关代码
import { removeKeyboardKey, addKeyboardKey } from '@/utils/keyboard'
export default {
created () {
// 添加监听
window.addEventListener('keydown', addKeyboardKey)
window.addEventListener('keyup', removeKeyboardKey)
// 记住添加事件和卸载事件老是成对存在
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('keydown', addKeyboardKey)
window.removeEventListener('keyup', removeKeyboardKey)
})
}
}
复制代码
至此咱们已经完成了记录页面中的当前按下按键。ui
咱们在路由的全局守卫 beforeEach
中添加控制的代码。this
// 下面只展现需求相关代码
import { isCtrlPress } from '@/utils/keyboard'
// 这里省略了router的建立,router是VueRouter的实例
router.beforeEach((to, from, next) => {
// 在每次路由跳转的时候进行判断
if (isCtrlPress()) {
// 若是 ctrl 按键被按下,则以新窗口打开目标页面
window.open('#' + to.fullPath)
// 并阻止当前页面的跳转
return next(false)
}
// 其余的代码,注意保证next至少和至多被调用一次
// ...
}
复制代码
如今咱们就已经完成了点击页面连接时按住 Ctrl
按键则以新窗口形式打开该页面 😀。spa
文章首发在个人我的博客,原文连接,欢迎转载,转载请注明出处 😀。code