zoukankan      html  css  js  c++  java
  • 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;
         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;
         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>
    

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

    在这里插入图片描述

    在这里插入图片描述

    【版权声明】本博文著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处!
    【重要说明】本文为本菜鸟的学习记录,论点和观点仅代表个人不代表此技术的真理,目的是学习和可能成为向别人分享的经验,因此有错误会虚心接受改正,但不代表此时博文无误!
    【博客园地址】JayveeWong: http://www.cnblogs.com/wjw1014
    【CSDN地址】JayveeWong: https://blog.csdn.net/weixin_42776111
    【Gitee地址】Jayvee:https://gitee.com/wjw1014
    【GitHub地址】Jayvee:https://github.com/wjw1014
  • 相关阅读:
    Keepalived案例一:Keepalived双机热备(HA)精讲
    Linux服务器挂载ntfs移动硬盘
    RAC 单节点实例异常关闭,关键报错ORA--29770
    模拟等待事件:db file sequential read
    使用dbms_stats.gather_table_stats调整表的统计信息
    oracle rac常用的网络检查命令
    收集Oracle数据库中的SQL基线信息(一)基础信息收集
    Oracle 通过sql profile为sql语句加hint
    将指定SQL的执行计划从共享池删除的方法
    数据库什么时候建立索引?
  • 原文地址:https://www.cnblogs.com/wjw1014/p/15066785.html
Copyright © 2011-2022 走看看