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 相关文章推荐
jQuery在vs2008及js文件中的无智能提示的解决方法
Dec 30 Javascript
Javascript操作cookie的函数代码
Oct 03 Javascript
jQuery.buildFragment使用方法及思路分析
Jan 07 Javascript
jQuery分组选择器用法实例
Dec 23 Javascript
JavaScript判断手机号运营商是移动、联通、电信还是其他(代码简单)
Sep 25 Javascript
动态加载js文件简单示例
Apr 21 Javascript
浅析jQuery中使用$所引发的问题
May 29 Javascript
Angular中的$watch方法详解
Sep 18 Javascript
解决vue 更改计算属性后select选中值不更改的问题
Mar 02 Javascript
Async/Await替代Promise的6个理由
Jun 15 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
Nov 14 Javascript
vue+vant 上传图片需要注意的地方
Jan 03 Vue.js
纯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
PHP遍历文件夹与文件类及处理类用法实例
2014/09/23 PHP
php获取汉字拼音首字母的方法
2015/10/21 PHP
PHP7.1方括号数组符号多值复制及指定键值赋值用法分析
2016/09/26 PHP
PHP读取word文档的方法分析【基于COM组件】
2017/08/01 PHP
php集成开发环境详解
2019/09/24 PHP
基于jquery的一个浮动框(扩展性比较好 )
2010/08/27 Javascript
javascript继承之为什么要继承
2012/11/10 Javascript
js判断上传文件的类型和大小示例代码
2013/10/18 Javascript
jQuery中Dom的基本操作小结
2014/01/23 Javascript
jQuery中focus事件用法实例
2014/12/26 Javascript
jQuery插件slides实现无缝轮播图特效
2015/04/17 Javascript
学习JavaScript设计模式(代理模式)
2015/12/03 Javascript
jquery获取select选中值的方法分析
2015/12/22 Javascript
微信公众号支付H5调用支付解析
2016/11/04 Javascript
JS闭包与延迟求值用法示例
2016/12/22 Javascript
ajax与json 获取数据并在前台使用简单实例
2017/01/19 Javascript
JavaScript获取当前时间向前推三个月的方法示例
2017/02/04 Javascript
微信小程序用户信息encryptedData详解
2018/08/24 Javascript
react 组件传值的三种方法
2019/06/03 Javascript
vue动态禁用控件绑定disable的例子
2019/10/28 Javascript
微信小程序页面间传递数组对象方法解析
2019/11/06 Javascript
js实现经典贪吃蛇小游戏
2020/03/19 Javascript
[01:29:46]DOTA2上海特级锦标赛C组资格赛#1 OG VS LGD第二局
2016/02/27 DOTA
python通过ftplib登录到ftp服务器的方法
2015/05/08 Python
python 实现将字典dict、列表list中的中文正常显示方法
2018/07/06 Python
Python实现查询某个目录下修改时间最新的文件示例
2018/08/29 Python
Django 数据库同步操作技巧详解
2019/07/19 Python
python 实现识别图片上的数字
2019/07/30 Python
python中selenium库的基本使用详解
2020/07/31 Python
css3实现背景模糊的三种方式(小结)
2020/05/15 HTML / CSS
手工制作的意大利皮革运动鞋:KOIO
2020/01/05 全球购物
linux面试题参考答案(11)
2016/11/26 面试题
初中班主任评语
2014/04/24 职场文书
2014年科研工作总结
2014/12/03 职场文书
关于环保的广播稿
2015/12/17 职场文书
vue2的 router在使用过程中遇到的一些问题
2022/04/13 Vue.js