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

 更新时间:2022年04月20日 14:45:53   作者:秦浩铖  
有的时候项目需要在页面使用快捷键,而且需要对快捷键进行维护。本文将为大家展示Vue实现快捷键录入功能的示例代码,感兴趣的可以了解一下

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

记录一下。

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

直接上代码:

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

相关文章

  • vue.js实现标签页切换效果

    vue.js实现标签页切换效果

    这篇文章主要介绍了vue.js实现标签页切换效果,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-06-06
  • 一文搞懂Vue3.2中setup语法糖使用

    一文搞懂Vue3.2中setup语法糖使用

    在vue3版本中,引入了一个新的函数,叫做setup。本文将通过实例为大家详细讲讲Vue3.2中setup语法糖的使用,感兴趣的小伙伴可以了解一下
    2022-07-07
  • vuex根据不同的用户权限展示不同的路由列表功能

    vuex根据不同的用户权限展示不同的路由列表功能

    最近接到一个新的需求,要求将系统的用户进行分类,用户登陆后根据不同的用户权限展示不同的功能列表。这篇文章主要介绍了vuex根据不同的用户权限展示不同的路由列表,需要的朋友可以参考下
    2019-09-09
  • vue3集成echarts数据刷新后图表不刷新的解决方法

    vue3集成echarts数据刷新后图表不刷新的解决方法

    vue3 集成 echarts 最大的坑就是出现了,reactive 的数据 刷新了,但图表缺不会刷新,所以本文就给大家详细的介绍一下vue3集成echarts数据刷新后图表不刷新的解决方法,需要的朋友可以参考下
    2023-08-08
  • vue+element多选级联选择器自定义props使用详解

    vue+element多选级联选择器自定义props使用详解

    这篇文章主要给大家介绍了关于vue+element多选级联选择器自定义props使用的相关资料,级联选择器展示的结果都是以数组的形式展示,也就是v-model绑定的结果,需要的朋友可以参考下
    2023-07-07
  • vue.js模版插值的原理与实现方法简析

    vue.js模版插值的原理与实现方法简析

    这篇文章主要介绍了vue.js模版插值的原理与实现方法,结合实例形式简单分析了vue.js模板插值的基本功能、原理、实现方法与注意事项,需要的朋友可以参考下
    2023-04-04
  • Vue中加载天地图的离线地图基本步骤

    Vue中加载天地图的离线地图基本步骤

    这篇文章主要给大家介绍了关于Vue中加载天地图的离线地图的基本步骤,Vue天地图离线地图是指基于Vue框架开发的应用程序,使用天地图离线地图服务提供商提供的地图数据,可以在没有网络的情况下使用地图功能,需要的朋友可以参考下
    2023-10-10
  • vue 的 solt 子组件过滤过程解析

    vue 的 solt 子组件过滤过程解析

    这篇文章主要介绍了vue 的 solt 子组件过滤过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Vue中的父子组件传值.sync

    Vue中的父子组件传值.sync

    这篇文章主要介绍了Vue中的父子组件传值.sync,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • vue引入组件的几种方法汇总

    vue引入组件的几种方法汇总

    这篇文章主要介绍了vue引入组件的几种方法汇总,包括常用的局部引入,这里需要注意在哪个页面需要就在那个页面引入、注册、使用,本文结合示例代码给大家介绍的非常详细,需要的朋友参考下吧
    2023-10-10

最新评论