• VUE扫码枪中文输入法兼容自动回车事件


    背景

    最近产品想要在页面上加一个input输入框,想要手动输入,也想要扫码枪扫描输入,大家都知道扫码枪扫描后会自动出发input的回车enter事件的,我当初也是这么认为的,所以在input上就直接绑定了keyup enter事件,在里面做一些接口请求之类的动作,后来这个页面被投放到门店的收银机,问题出现了:当机器为windows系统并且搜狗输入法中文时,扫码枪没有监听到自动回车事件,导致扫描枪没反应

    解决方案

    password的Input可以忽略输入法的中英文,所以password框里的内容,我们需要一个覆盖在上面的div来实时展示,这个div要像一个input存在,所以要模拟一个失焦和聚焦的闪烁光标,光标闪烁时真正聚焦的是password input框

    需求设计

    1. 一个div和一个type为password ,两者数据实时绑定
    2. div覆盖在password上,设定一个伪类来实现div的闪烁光标
    3. password的focus和blur方法中控制div的光标是否显示
    4. div的不设宽度,促使光标紧随div内容后面

    代码

    先写一个barcode.vue的子组件

    <template>
      <div style="position: relative;width: 200px;">
        <el-input
          type="password"
          v-model="barCode"
          autocomplete="off"
          class="pad-input"
          ref="barcodeScanRef"
          @keyup.enter.native="enterHandle"
          @focus="handleInputFocus"
          @blur="handleInputBlur"
        ></el-input>
        <div id="show" disabled>
          <span>{{ barCode }}</span>
        </div>
      </div>
    </template>
    <script>
    export default {
      props: {
        enterHandle: {
          type: Function,
          default: () => () => {},
        },
      },
      data() {
        return {
          barCode: '',
        };
      },
      methods: {
        handleInputBlur() {
          this.handleMymove('0');
        },
        handleInputFocus(e) {
          this.handleMymove('1');
        },
        handleMymove(num) {
          let style = document.createElement('style');
          document.head.appendChild(style);
          let sheet = style.sheet;
          sheet.addRule('#show:after', `opacity:${num};animation:${num==='0'?'null':'mymove 1.2s infinite'} `);
          sheet.insertRule(`#show:after{opacity:${num};animation:${num==='0'?'null':'mymove 1.2s infinite'}}`);
        },
      },
    };
    </script>
    <style lang="less">
    #show {
      padding-left: 14px;
      position: absolute;
      left: 2px;
      top: 50%;
      transform: translate(0, -50%);
      border: none;
      height: 30px;
      line-height: 30px;
      pointer-events: none;
      background: #fff;
      width: 98%;
    }
    #show:after {
      content: '';
      display: inline-block;
      height: 15px;
      position: relative;
      border-right: solid 1px #666;
      top: 2px;
      left: 1px;
      opacity: 0;
    }
    .pad-input {
      height: 28px;
      width: 100%;
      border: none;
      background: none;
    }
    @keyframes mymove {
      0% {
        opacity: 0;
      }
      25% {
        opacity: 0;
      }
      75% {
        opacity: 1;
      }
      100% {
        opacity: 0;
      }
    }
    </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

    父组件调用,传递一个子组件回车事件enterHandle

    <template>
        <el-form-x v-bind="formProps" @submit.native.prevent ref="form">
          <el-form-item label="分配单号" prop="paperCode" :wrapper-col="{ span: 6 }">
            <barcode-scan :enterHandle="handleAdd" ref="barcodeRef"></barcode-scan>
          </el-form-item>
          <div class="pseudo-form-item">
            <el-button type="primary" @click="handleAdd">添加 </el-button>
          </div>
        </el-form-x>
    </template>
    <script>
    import barcodeScan from '../../components/barcode-scan.vue';
    export default {
      components: {
        barcodeScan,
      },
      methods: {
        async handleAdd() {
          let barcodeRef = this.$refs.barcodeRef;
          if (!barcodeRef.barCode && !barcodeRef_data.barCode) {
            return this.$message.error('请输入单号');
          }
          this.formProps.model.paperCode = barcodeRef.barCode || barcodeRef_data.barCode;
          try {
            const { paperCode } = this.formProps.model;
            if (!paperCode) return;
            ...//发送请求处理数据
          } catch (e) {
            e.data && this.$message.error(e.data.msg);
          }
          //请求完之后再自动去聚焦
          barcodeRef.$refs.barcodeScanRef.select();
          barcodeRef.$refs.barcodeScanRef.focus();
          barcodeRef.barCode = '';
          barcodeRef._data.barCode = '';
        },
    };
    </script>
    
    • 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

    这样就可以解决vue框架下面的扫描枪或者手动输入遇到的搜狗输入法兼容性问题

    到了这里你以为就结束了么?过了不久,门店的人又来反馈了: 当鼠标聚焦时,"输入框"旁边会出现密码自动填充的弹窗,这是浏览器自带的,事情变的有趣了…
    VUE扫码枪中文输入法兼容自动回车事件(下)

  • 相关阅读:
    代码随想录算法训练营第五十九天| 647.回文子串 、516.最长回文子序列
    2023年视频号视频下载提取使用教程
    图书推荐管理系统Python+Django网页界面+协同过滤推荐算法
    数据结构——栈的详细介绍
    如何实现罗克韦尔PLC AB1756的远程监控数据采集?
    Sementic Kernel 案例之网梯科技在线教育
    [DownUnderCTF 2022] crypto部分复现
    Mutated 源代码解析 client (一)
    element ui+vue实现导航栏菜单以及页面跳转
    【 云原生 | K8S 】kubectl 详解
  • 原文地址:https://blog.csdn.net/MichelleZhai/article/details/127667415