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 相关文章推荐
this[] 指的是什么内容 讨论
Mar 24 Javascript
传递参数的标准方法(jQuery.ajax)
Nov 19 Javascript
JavaScript中字符串分割函数split用法实例
Apr 07 Javascript
js实现表单Radio切换效果的方法
Aug 17 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
Jan 13 Javascript
jquery设置css样式的多种方法(总结)
Feb 21 Javascript
深入理解vue-loader如何使用
Jun 06 Javascript
Chart.js 轻量级HTML5图表绘制工具库(知识整理)
May 22 Javascript
Echarts地图添加引导线效果(labelLine)
Sep 30 Javascript
JS数组方法slice()用法实例分析
Jan 18 Javascript
JavaScript组合设计模式--改进引入案例分析
May 23 Javascript
element tree树形组件回显数据问题解决
Aug 14 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
php实现的遍历文件夹下所有文件,编辑删除
2010/01/05 PHP
开启CURL扩展,让服务器支持PHP curl函数(远程采集)
2011/03/19 PHP
php中的注释、变量、数组、常量、函数应用介绍
2012/11/16 PHP
作为PHP程序员应该了解MongoDB的五件事
2013/06/03 PHP
浅析php中如何在有限的内存中读取大文件
2013/07/02 PHP
php 读取文件头判断文件类型的实现代码
2013/08/05 PHP
PHP生成随机密码类分享
2014/06/25 PHP
smarty自定义函数htmlcheckboxes用法实例
2015/01/22 PHP
php数组函数array_key_exists()小结
2015/12/10 PHP
JS中==与===操作符的比较
2009/03/21 Javascript
js中有关IE版本检测
2012/01/04 Javascript
JS时间选择器 兼容IE6,7,8,9
2012/06/26 Javascript
基于iframe实现类似于ajax的页面无刷新
2014/05/31 Javascript
jQuery中closest()函数用法实例
2015/01/07 Javascript
javascript基本包装类型介绍
2015/04/10 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
Bootstrap优化站点资源、响应式图片、传送带使用详解3
2016/10/14 Javascript
基于JavaScript实现前端文件的断点续传
2016/10/17 Javascript
详解Nodejs的timers模块
2016/12/22 NodeJs
这应该是最详细的响应式系统讲解了
2019/07/22 Javascript
layui实现下拉框三级联动
2019/07/26 Javascript
layui实现数据表格点击搜索功能
2020/03/26 Javascript
JS中封装axios来管控api的2种方式
2019/09/11 Javascript
js实现九宫格抽奖
2020/03/19 Javascript
Python使用scrapy抓取网站sitemap信息的方法
2015/04/08 Python
Python使用Windows API创建窗口示例【基于win32gui模块】
2018/05/09 Python
Keras模型转成tensorflow的.pb操作
2020/07/06 Python
Python字典dict常用方法函数实例
2020/11/09 Python
python3中TQDM库安装及使用详解
2020/11/18 Python
CSS3制作炫酷的下拉菜单及弹起式选单的实例分享
2016/05/17 HTML / CSS
致全体运动员广播稿
2014/02/01 职场文书
英语自我介绍演讲稿
2014/09/01 职场文书
商务邀请函
2015/01/30 职场文书
python3.9之你应该知道的新特性详解
2021/04/29 Python
零基础学java之循环语句的使用
2022/04/10 Java/Android
SQL Server 中的事务介绍
2022/05/20 SQL Server