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实际应用:innerHTMl和确认提示的使用
Jun 22 Javascript
jQuery 翻牌或百叶窗效果(内容三秒自动切换)
Jun 14 Javascript
jquery easyui combox一些实用的小方法
Dec 25 Javascript
使用原生js写的一个简单slider
Apr 29 Javascript
推荐 21 款优秀的高性能 Node.js 开发框架
Aug 18 Javascript
使用javascript获取页面名称
Dec 23 Javascript
jQuery插件jFade实现鼠标经过的图片高亮其它变暗
Mar 14 Javascript
javascript基于prototype实现类似OOP继承的方法
Dec 16 Javascript
基于jquery编写的放大镜插件
Mar 23 Javascript
vue中node_modules中第三方模块的修改使用详解
May 31 Javascript
JS 事件机制完整示例分析
Jan 15 Javascript
Vue如何基于vue-i18n实现多国语言兼容
Jul 17 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
smarty模板引擎使用内建函数foreach循环取出所有数组值的方法
2015/01/22 PHP
php文件上传、下载和删除示例
2020/08/28 PHP
php基于闭包实现函数的自调用(递归)实例分析
2016/11/11 PHP
Yii 2.0实现联表查询加搜索分页的方法示例
2017/08/02 PHP
让您的菜单不离网站
2006/10/03 Javascript
JavaScript修改css样式style
2008/04/15 Javascript
JQuery入门—JQuery程序的代码风格详细介绍
2013/01/03 Javascript
SWFObject基本用法实例分析
2015/07/20 Javascript
浅谈JS继承_寄生式继承 &amp; 寄生组合式继承
2016/08/16 Javascript
基于javascript实现最简单选项卡切换
2017/02/01 Javascript
Bootstrap媒体对象学习使用
2017/03/07 Javascript
React简单介绍
2017/05/24 Javascript
form表单数据封装成json格式并提交给服务器的实现方法
2017/12/14 Javascript
原生js调用json方法总结
2018/02/22 Javascript
js构建二叉树进行数值数组的去重与优化详解
2018/03/26 Javascript
详解ES6 Promise对象then方法链式调用
2018/10/20 Javascript
JS实现图片切换特效
2019/12/23 Javascript
微信小程序以ssm做后台开发的实现示例
2020/04/08 Javascript
ant-design-vue 时间选择器赋值默认时间的操作
2020/10/27 Javascript
python中List的sort方法指南
2014/09/01 Python
python使用logging模块发送邮件代码示例
2018/01/18 Python
Flask模拟实现CSRF攻击的方法
2018/07/24 Python
对Python生成汉字字库文字,以及转换为文字图片的实例详解
2019/01/29 Python
python实现文法左递归的消除方法
2020/05/22 Python
Python如何输出整数
2020/06/07 Python
Python函数参数定义及传递方式解析
2020/06/10 Python
总经理助理的职责
2014/03/14 职场文书
函授毕业生自我鉴定范文
2014/03/25 职场文书
文明生主要事迹
2014/05/25 职场文书
幼儿园保育员责任书
2014/07/22 职场文书
乡镇遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
党员个人剖析材料(四风问题)
2014/10/07 职场文书
先进教育工作者事迹材料
2014/12/23 职场文书
语文教师个人工作总结
2015/02/06 职场文书
2016年万圣节活动总结
2016/04/05 职场文书
JavaScript原始值与包装对象的详细介绍
2021/05/11 Javascript