0
点赞
收藏
分享

微信扫一扫

vue 实现快捷键录入功能

vue 实现快捷键录入功能

项目需要在页面使用快捷键,而且需要对快捷键进行维护,然后呢,就从网上抄了,改成自己的。

记录一下。

参考地址: ​​https://www.jb51.net/article/203981.htm​​

首先有一个组件,用来实现快捷键的录入操作。

直接上代码:

hotkeyInput.vue

<doc>
快捷键输入框 —— 用于快捷键的录入
</doc>
<template>
<div class="shortcut-key-input" :class="{ cursor: focus }" :style="$props.style" tabindex="0" @focus="handleFocus"
@blur="focus = false" @keydown="handleKeydown">
<template v-if="list.length">
<template v-for="(item, index) in list">
<span :key="`${item.text}_${index}`">{{ item.text }} <i @click="handleDeleteKey(index)"></i></span>
</template>
</template>
<div v-else class="placeholder">{{ placeholder }}</div>
</div>
</template>

<script>
const CODE_NUMBER = Array.from({ length: 10 }, (v, k) => `Digit${k + 1}`);
const CODE_NUMPAD = Array.from({ length: 10 }, (v, k) => `Numpad${k + 1}`);
const CODE_ABC = Array.from(
{ length: 26 },
(v, k) => `Key${String.fromCharCode(k + 65).toUpperCase()}`
);
const CODE_FN = Array.from({ length: 12 }, (v, k) => `F${k + 1}`);
const CODE_CONTROL = [
"Shift",
"ShiftLeft",
"ShiftRight",
"Control",
"ControlLeft",
"ControlRight",
"Alt",
"AltLeft",
"AltRight",
]; // ShiftKey Control(Ctrl) Alt

export default {
name: "HotKeyInput",
props: {
// 默认绑定值
// 传入 ['Ctrl+d'] 格式时会自动处理成 [{ text: 'Ctrl+d', controlKey: { altKey: false, ctrlKey: true, shiftKey: false, key: 'd', code: 'KeyD } }]
hotkey: {
type: Array,
required: true,
},
// 校验函数 判断是否允许显示快捷键
verify: {
type: Function,
default: () => true,
},
// 无绑定时提示文字
placeholder: {
type: String,
default: "",
},
// 限制最大数量
max: {
type: [String, Number],
default: 1,
},
// 快捷键使用范围
range: {
type: Array,
default: () => ["NUMBER", "NUMPAD", "ABC", "FN"],
},
},
data() {
return {
focus: false,
list: this.hotkey,
keyRange: [],
};
},
watch: {
list: function (list) {
if (list.length) this.focus = false;
this.$emit("update:hotkey", this.list);
},
hotkey: {
handler: function (val) {
if (!val.length) return;
const list = [];
val.forEach((item) => {
const arr = item.split("+");
const controlKey = {
altKey: arr.includes("Alt"),
ctrlKey: arr.includes("Control"),
shiftKey: arr.includes("Shift"),
key: arr[arr.length - 1],
code: `Key${arr[arr.length - 1].toUpperCase()}`,
};
list.push({
text: arr.reduce((text, item, i) => {
if (i) text += "+";
if (controlKey.key === item) text += item.toUpperCase();
else text += item;
return text;
}, ""),
controlKey,
});
});
this.list = list;
},
immediate: true,
},
range: {
handler: function (val) {
const keyRangeList = {
NUMBER: CODE_NUMBER,
NUMPAD: CODE_NUMPAD,
ABC: CODE_ABC,
FN: CODE_FN,
};
val.forEach((item) => {
this.keyRange = this.keyRange.concat(
keyRangeList[item.toUpperCase()]
);
});
},
immediate: true,
},
},
methods: {
handleFocus() {
if (!this.list.length) this.focus = true;
},
handleDeleteKey(index) {
this.list.splice(index, 1);
},
handleKeydown(e) {
const { altKey, ctrlKey, shiftKey, key, code } = e;
if (!CODE_CONTROL.includes(key)) {
if (!this.keyRange.includes(code)) return;
let controlKey = "";
[
{ key: altKey, text: "Alt" },
{ key: ctrlKey, text: "Ctrl" },
{ key: shiftKey, text: "Shift" },
].forEach((curKey) => {
if (curKey.key) {
if (controlKey) controlKey += "+";
controlKey += curKey.text;
}
});
if (key) {
if (controlKey) controlKey += "+";
controlKey += key.toUpperCase();
}
this.addHotkey({
text: controlKey,
controlKey: { altKey, ctrlKey, shiftKey, key, code },
});
}
e.preventDefault();
},
addHotkey(data) {
if (this.list.length && this.list.some((item) => data.text === item.text))
return;
if (
this.list.length &&
this.list.length.toString() === this.max.toString()
)
return;
this.list.push(data);
},
},
};
</script>

<style scoped>
@keyframes Blink {
0% {
opacity: 0;
}

100% {
opacity: 1;
}
}

.shortcut-key-input {
position: relative;
border: 1px solid #dcdcdc;
border-radius: 4px;
background-color: #fff;
color: #333;
width: 100%;
height: 40px;
/* padding: 2px 0; */
cursor: text;
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
}

.shortcut-key-input:focus {
border-color: #188cff;
box-shadow: 0 0 4px rgba(24, 140, 255, 0.38);
}

.shortcut-key-input.cursor::after {
content: "|";
animation: Blink 1.2s ease 0s infinite;
font-size: 18px;
position: absolute;
top: 2px;
left: 12px;
}

.shortcut-key-input span {
position: relative;
display: inline-block;
box-sizing: border-box;
background-color: #f4f4f5;
border-color: #e9e9eb;
color: #909399;
padding: 0 22px 0 8px;
height: 28px;
font-size: 13px;
line-height: 28px;
border-radius: 4px;
margin: 5px;
}

.shortcut-key-input .placeholder {
position: absolute;
top: 10px;
left: 11px;
color: #c0c4cc;
font-size: 13px;
text-indent: 4px;
font: 400 13.3333px Arial;
}

.shortcut-key-input span i {
position: absolute;
top: 6px;
right: 4px;
content: "";
background: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M512 64C264.58 64 64 264.58 64 512s200.58 448 448 448 448-200.58 448-448S759.42 64 512 64zm0 832c-212.08 0-384-171.92-384-384s171.92-384 384-384 384 171.92 384 384-171.92 384-384 384z' fill='%23909399'/%3E%3Cpath d='M625.14 353.61L512 466.75 398.86 353.61a32 32 0 0 0-45.25 45.25L466.75 512 353.61 625.14a32 32 0 0 0 45.25 45.25L512 557.25l113.14 113.14a32 32 0 0 0 45.25-45.25L557.25 512l113.14-113.14a32 32 0 0 0-45.25-45.25z' fill='%23909399'/%3E%3C/svg%3E") no-repeat center;
background-size: contain;
width: 14px;
height: 14px;
transform: scale(0.9);
opacity: 0.6;
}

.shortcut-key-input span i:hover {
cursor: pointer;
opacity: 1;
}
</style>

然后需要的地方引用一下。

import hotkeyInput from '@/views/modules/hotkeyInput'
components: {
hotkeyInput,
},
<hotkey-input v-if="dialogVisible" :hotkey.sync="form.shortcutKey" placeholder="请按需要绑定的按键,支持组合按键"></hotkey-input>

但是吧,选择之后的数据是这个样子的:

vue 实现快捷键录入功能_快捷键

vue 实现快捷键录入功能_git_02

【版权声明】本博文著作权归作者所有,任何形式的转载都请联系作者获取授权并注明出处!

【重要说明】本文为本人的学习记录,论点和观点仅代表个人而不代表当时技术的真理,目的是自我学习和有幸成为可以向他人分享的经验,因此有错误会虚心接受改正,但不代表此刻博文无误!

【Gitee地址】秦浩铖:​​https://gitee.com/wjw1014​​


举报

相关推荐

0 条评论