文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue实现快捷键录入功能的示例代码

2024-04-02 19:55

关注

项目需要在页面使用快捷键,而且需要对快捷键进行维护,然后参考了此篇文章,改成自己的。

记录一下。

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

直接上代码:

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;
    
    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快捷键录入内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯