• vue触屏项目 使用 虚拟键盘组件,通过js给el-input value赋值,v-model绑定值不同步问题(已修改)


    1.管理后台项目 每个页面都有模糊搜索,之前是使用外接键盘或者扫码枪进行输入,完全没有问题,但是最近客户使用的是触屏手动输入,就发现了问题,输入框上的值并不会被监听到,也不会触发el-input框自带的enter,以及change事件,这时候就想着接入一个 虚拟键盘,在触屏项目中使用,接入完成后本以为可以成功,但是发现,通过js给el-input value赋值,v-model绑定值不会同步
    在这里插入图片描述
    问题:.赋值后,界面显示字段已更改,获取v-model的参数,发现不会同步更改

    解决办法:
    v-model只是一种语法糖,底层的方法还是去监听input事件。所以可以使用dispatchEvent事件给元素分配一个input事件,这样可以手动触发 inputElement 的 input 事件,同时可以触发 v-model 机制。IE 好像不支持(但可以 polyfill)。

    el.value(newval)
    
    el.dispatchEvent(new Event(\'input\'));
    
    el为input元素
    
    • 1
    • 2
    • 3
    • 4
    • 5

    解决!

    PS:

    如果v-model有lazy修饰符的时候,触发得是change事件
    el.dispatchEvent(new Event(‘change’));

    完整步骤:

    1.先安装

        npm i simple-keyboard -S
    
    • 1

    2.我这里是单独写了一个keyboard.vue的组件
    在这里插入图片描述

    <template>
      <div :class="keyboardClass"></div>
    </template>
    
    <script>
    import Keyboard from "simple-keyboard";
    import "simple-keyboard/build/css/index.css";
    
    export default {
      name: "SimpleKeyboard",
      props: {
        keyboardClass: {
          default: "simple-keyboard",
          type: String,
        },
        input: {
          type: String,
        },
        layout: {
          type: Object,
          default: function () {
            return {
              default: [
                "` 1 2 3 4 5 6 7 8 9 0 - = {bksp}",
                "{tab} q w e r t y u i o p [ ] \\",
                "{lock} a s d f g h j k l ; ' {enter}",
                "{shift} z x c v b n m , . / {shift}",
                "@ {space}",
              ],
              shift: [
                "~ ! @ # $ % ^ & * ( ) _ + {bksp}",
                "{tab} Q W E R T Y U I O P { } |",
                '{lock} A S D F G H J K L : " {enter}',
                "{shift} Z X C V B N M < > ? {shift}",
                "@ {space}",
              ],
            };
          },
        },
      },
      data: () => ({
        keyboard: null,
      }),
      mounted() {
        this.keyboard = new Keyboard(this.keyboardClass, {
          onChange: this.onChange,
          onKeyPress: this.onKeyPress,
        });
        this.keyboard.setOptions({
          layoutName: "default",
          layout: this.layout,
          display: {
            "{enter}": "close",
            "{shift}": "shift",
            "{bksp}": "del",
            "{tab}": "tab",
            "{space}": "space",
            "{lock}": "caps",
          },
        });
      },
      methods: {
        onChange(input) {
          this.$emit("onChange", input);
        },
        onKeyPress(button) {
          this.$emit("onKeyPress", button);
    
          /**
           * If you want to handle the shift and caps lock buttons
           */
          if (button === "{shift}" || button === "{lock}") this.handleShift();
        },
        handleShift() {
          let currentLayout = this.keyboard.options.layoutName;
          let shiftToggle = currentLayout === "default" ? "shift" : "default";
    
          this.keyboard.setOptions({
            layoutName: shiftToggle,
          });
        },
      },
      watch: {
        input(input) {
          this.keyboard.setInput(input);
        },
      },
    };
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    tips: 因为我这边有几个键需要自定义,所以在mounted中进行了修改~

    3. 在需要应用的页面 引入 注册 使用即可 我这里是在keyIndex.vue页面中引入啦~
    在这里插入图片描述

    <template>
      <div>
        <svg-icon icon-class="keyboard" @click="click" />
        <SimpleKeyboard
          v-if="isShow"
          @onChange="onChange"
          @onKeyPress="onKeyPress"
          :input="input"
        />
      </div>
    </template>
    
    <script>
    import SimpleKeyboard from "@/components/keyboard/keyboard";
    export default {
      name: "keyboard",
      components: { SimpleKeyboard },
      data() {
        return {
          input: "",
          currentInputDom: "",
          isShow: false,
        };
      },
      beforeUpdate() {
        this.$nextTick(() => {
          this.findInput();
        });
      },
      methods: {
        click() {
          this.isShow = !this.isShow;
        },
        onChange(input) {
          console.log(input, "input");
          let that = this;
          that.input = input;
          that.currentInputDom.value = input + "";
          that.currentInputDom.dispatchEvent(new Event("input"));
        },
        onKeyPress(button) {
          let that = this;
          if (button == "{enter}") {
            that.isShow = false;
          }
        },
        //给页面中input框添加点击事件
        findInput() {
          let that = this;
          let list = document.getElementsByTagName("input");
          for (let i = 0; i < list.length; i++) {
            let inputDom = list[i];
            if (inputDom.type == "text" || inputDom.type == "password") {
              console.log(inputDom.readOnly, i);
              if (!inputDom.readOnly) {
                inputDom.addEventListener("click", function (event) {
                  that.input = event.target.value; //获取到输入框的值
                  that.currentInputDom = event.target;
                });
                // console.log(inputDom.type, i);
              }
            }
          }
        },
      },
    };
    </script>
    
    <style scoped>
    .keyboard-svg {
      display: inline-block;
      cursor: pointer;
      fill: #5a5e66;
      width: 20px;
      height: 20px;
      vertical-align: 10px;
    }
    
    .hg-theme-default {
      position: fixed;
      z-index: 9999;
      width: 75%;
      left: 20%;
      bottom: 30px;
    }
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    tips:因为每个页面都有input框,所以我这边写了一个方法 findInput(),找到页面中所有的input框并添加点击事件,获取到输入的值。
    1.首先:给页面中input框添加点击事件,也要区分因为日期选择器,下拉框噢。本质上也属于输入框,但它们不是真的哦~
    所以:inputDom.type == “text” || inputDom.type == "password"时,添加点击事件
    2.

     inputDom.addEventListener("click", function (event) {
     //js赋值
                  that.input = event.target.value; 
                  that.currentInputDom = event.target; 
     });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.onChange事件 是键盘按键 点击时触发

       onChange(input) {
       //input: 为点击的键盘值
          console.log(input, "input");
          let that = this;
          that.input = input;// 赋值给键盘上绑定的值
          that.currentInputDom.value = input + ""; //value  值格式为字符串,所以要+ ''
          that.currentInputDom.dispatchEvent(new Event("input")); //更新v-model的值
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    实现效果 :点击旁边的搜索功能也是最新输入的值噢~ 更新成功

    在这里插入图片描述

  • 相关阅读:
    Kamiya丨Kamiya艾美捷小鼠脱细胞素ELISA说明书
    【Git-11】Eclipse中Git冲突管理
    独立双样本T-Test 前 为什么要先进行列文检验(Levene‘s Test)
    数据库MySQL中Show指令祥解
    实战使用Airtest与mitmdump爬取app数据
    Python基础tuple元组定义与函数
    人工智能:创新之路
    手把手教你如何采用服务商模式实现微信支付
    看完这篇,医学小白也能轻松玩转文献查阅
    软件测试学习笔记丨Selenium复用已打开浏览器
  • 原文地址:https://blog.csdn.net/Maxueyingying/article/details/126503771