vue实现一个6个输入框的验证码输入组件功能的实例代码


Posted in Javascript onJune 29, 2020

vue实现一个6个输入框的验证码输入组件功能的实例代码

要实现的功能:

完全和单输入框一样的操作,甚至可以插入覆盖:

1,限制输入数字

2,正常输入

3,backspace删除

4,paste任意位置粘贴输入

5,光标选中一个数字,滚轮可以微调数字大小,限制0-9

6,123|456 自动覆盖光标后输入的字符,此时光标在3后,继续输入111,会得到123111,而不用手动删除456

7,封装成vue单文件组件,方便任意调用。

模板代码

<template>
  <div class="input-box">
    <div class="input-content" @keydown="keydown" @keyup="keyup" @paste="paste" @mousewheel="mousewheel"
        @input="inputEvent">
      <input max="9" min="0" maxlength="1" data-index="0" v-model.trim.number="input[0]" type="number"
          ref="firstinput"/>
      <input max="9" min="0" maxlength="1" data-index="1" v-model.trim.number="input[1]" type="number"/>
      <input max="9" min="0" maxlength="1" data-index="2" v-model.trim.number="input[2]" type="number"/>
      <input 
      <input max="9" min="0" maxlength="1" data-index="4" v-model.trim.number="input[4]" type="number"/>
      <input max="9" min="0" maxlength="1" data-index="5" v-model.trim.number="input[5]" type="number"/>
    </div>
  </div>
</template>

实现了键盘的keydown/keyup/paste/input和鼠标滚轮mousewheel事件

使用了6个输入框的方案来实现。

样式部分:使用了scss模式

<style scoped lang="scss">
  .input-box {
    .input-content {
      width: 512px;
      height: 60px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      
      input {
        color: inherit;
        font-family: inherit;
        border: 0;
        outline: 0;
        border-bottom: 1px solid #919191;
        height: 60px;
        width: 60px;
        font-size: 44px;
        text-align: center;
      }
    }
    
    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
      appearance: none;
      margin: 0;
    }
  }
</style>

具体实现逻辑:主要实现以上几个键盘事件操作。

<script>
  export default {
    data() {
      return {
        // 存放粘贴进来的数字
        pasteResult: [],
      };
    },
    props: ['code'],
    computed: {
      input() {
        // code 是父组件传进来的默认值,必须是6位长度的数组,这里就不再做容错判断处理
        // 最后空数组是默认值
        return this.code || this.pasteResult.length === 6 ? this.pasteResult : ['', '', '', '', '', '']
      }
    },
    methods: {
      // 解决一个输入框输入多个字符
      inputEvent(e) {
        var index = e.target.dataset.index * 1;
        var el = e.target;
        this.$set(this.input, index, el.value.slice(0, 1))
      },
      keydown(e) {
        var index = e.target.dataset.index * 1;
        var el = e.target;
        if (e.key === 'Backspace') {
          if (this.input[index].length > 0) {
            this.$set(this.input, index, '')
          } else {
            if (el.previousElementSibling) {
              el.previousElementSibling.focus()
              this.$set(this.input, index - 1, '')
            }
          }
        } else if (e.key === 'Delete') {
          if (this.input[index].length > 0) {
            this.$set(this.input, index, '')
          } else {
            if (el.nextElementSibling) {
              this.$set(this.input, index = 1, '')
            }
          }
          if (el.nextElementSibling) {
            el.nextElementSibling.focus()
          }
        } else if (e.key === 'Home') {
          el.parentElement.children[0] && el.parentElement.children[0].focus()
        } else if (e.key === 'End') {
          el.parentElement.children[this.input.length - 1] && el.parentElement.children[this.input.length - 1].focus()
        } else if (e.key === 'ArrowLeft') {
          if (el.previousElementSibling) {
            el.previousElementSibling.focus()
          }
        } else if (e.key === 'ArrowRight') {
          if (el.nextElementSibling) {
            el.nextElementSibling.focus()
          }
        } else if (e.key === 'ArrowUp') {
          if (this.input[index] * 1 < 9) {
            this.$set(this.input, index, (this.input[index] * 1 + 1).toString());
          }
        } else if (e.key === 'ArrowDown') {
          if (this.input[index] * 1 > 0) {
            this.$set(this.input, index, (this.input[index] * 1 - 1).toString());
          }
        }
      },
      keyup(e) {
        var index = e.target.dataset.index * 1;
        var el = e.target;
        if (/Digit|Numpad/i.test(e.code)) {
          this.$set(this.input, index, e.code.replace(/Digit|Numpad/i, ''));
          el.nextElementSibling && el.nextElementSibling.focus();
          if (index === 5) {
            if (this.input.join('').length === 6) {
              document.activeElement.blur();
              this.$emit('complete', this.input);
            }
          }
        } else {
          if (this.input[index] === '') {
            this.$set(this.input, index, '');
          }
        }
      },
      mousewheel(e) {
        var index = e.target.dataset.index;
        if (e.wheelDelta > 0) {
          if (this.input[index] * 1 < 9) {
            this.$set(this.input, index, (this.input[index] * 1 + 1).toString());
          }
        } else if (e.wheelDelta < 0) {
          if (this.input[index] * 1 > 0) {
            this.$set(this.input, index, (this.input[index] * 1 - 1).toString());
          }
        } else if (e.key === 'Enter') {
          if (this.input.join('').length === 6) {
            document.activeElement.blur();
            this.$emit('complete', this.input);
          }
        }
      },
      paste(e) {
        // 当进行粘贴时
        e.clipboardData.items[0].getAsString(str => {
          if (str.toString().length === 6) {
            this.pasteResult = str.split('');
            document.activeElement.blur();
            this.$emit('complete', this.input);
          }
        })
      }
    },
    mounted() {
      // 等待dom渲染完成,在执行focus,否则无法获取到焦点
      this.$nextTick(() => {
        this.$refs.firstinput.focus()
      })
    },
  }
</script>

如果你发现了bug,或者有优化空间,欢迎你的指正和建议。我会随时更新到原代码当中,分享给大家。

到此这篇关于vue实现一个6个输入框的验证码输入组件的文章就介绍到这了,更多相关vue实现输入框的验证码输入组件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
解析javascript系统错误:-1072896658的解决办法
Jul 08 Javascript
判断浏览器的内核及版本号方法汇总
Jan 05 Javascript
js实现每日自动换一张图片的方法
May 04 Javascript
angular.js分页代码的实例
Jul 27 Javascript
easyui tree带checkbox实现单选的简单实例
Nov 07 Javascript
js实现二级导航功能
Mar 03 Javascript
BootStrap表单宽度设置方法
Mar 10 Javascript
详解Angular 4.x Injector
May 04 Javascript
JS常见DOM节点操作示例【创建 ,插入,删除,复制,查找】
May 14 Javascript
vue 实现数字滚动增加效果的实例代码
Jul 06 Javascript
解决Vue-cli npm run build生产环境打包,本地不能打开的问题
Sep 20 Javascript
详解Angular模板引用变量及其作用域
Nov 23 Javascript
纯JS开发baguetteBox.js响应式画廊插件
Jun 28 #Javascript
JavaScript图片旋转效果实现方法详解
Jun 28 #Javascript
javascript+css实现俄罗斯方块小游戏
Jun 28 #Javascript
详解小程序横屏方案对比
Jun 28 #Javascript
微信小程序实现上传多张图片、删除图片
Jul 29 #Javascript
js模拟实现百度搜索
Jun 28 #Javascript
微信小程序地图实现展示线路
Jul 29 #Javascript
You might like
地球防卫队:陪着奥特曼打小怪兽的人类力量 那些经典队服
2020/03/08 日漫
PHP树的代码,可以嵌套任意层
2006/10/09 PHP
兼容性最强的PHP生成缩略图的函数代码(修改版)
2011/01/18 PHP
PHP设计模式之抽象工厂模式实例分析
2019/03/25 PHP
Javascript下的keyCode键码值表
2007/04/10 Javascript
javascript 获取表单file全路径
2009/12/31 Javascript
JS异常处理的一个想法(sofish)
2013/03/14 Javascript
按下Enter焦点移至下一个控件的实现js代码
2013/12/11 Javascript
jQuery中offset()方法用法实例
2015/01/16 Javascript
基于ES6 Array.of的用法(实例讲解)
2017/09/05 Javascript
JavaScript 中Date对象的格式化代码方法汇总
2017/09/06 Javascript
JavaScript中运算符规则和隐式类型转换示例详解
2017/09/06 Javascript
为vue-router懒加载时下载js的过程中添加loading提示避免无响应问题
2018/04/03 Javascript
重学JS 系列:聊聊继承(推荐)
2019/04/11 Javascript
关于vue-cli 3配置打包优化要点(推荐)
2019/04/22 Javascript
jQuery Migrate 插件用法实例详解
2019/05/22 jQuery
JS实现图片幻灯片效果代码实例
2020/05/21 Javascript
[00:32]DOTA2上海特级锦标赛 COL战队宣传片
2016/03/04 DOTA
安装Python和pygame及相应的环境变量配置(图文教程)
2017/06/04 Python
python模块之time模块(实例讲解)
2017/09/13 Python
Django中的文件的上传的几种方式
2018/07/23 Python
对Django中static(静态)文件详解以及{% static %}标签的使用方法
2019/07/28 Python
pygame实现俄罗斯方块游戏(对战篇1)
2019/10/29 Python
python实现ftp文件传输功能
2020/03/20 Python
在Matplotlib图中插入LaTex公式实例
2020/04/17 Python
Python hashlib模块的使用示例
2020/10/09 Python
html5如何及时更新缓存文件(js、css或图片)
2013/06/24 HTML / CSS
土木工程应届生求职信
2013/10/31 职场文书
应届毕业生的自我鉴定
2013/11/13 职场文书
学生会副主席竞聘书
2014/03/31 职场文书
预防艾滋病宣传标语
2014/06/25 职场文书
2014酒店客房部工作总结
2014/12/16 职场文书
小学语文教师竞聘演讲稿范文
2019/08/09 职场文书
解决Golang time.Parse和time.Format的时区问题
2021/04/29 Golang
SONY600GR,国产收音机厂商永远的痛
2022/04/05 无线电
Python+Pillow+Pytesseract实现验证码识别
2022/05/11 Python