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 闭包在封装函数时的简单分析
Nov 28 Javascript
js判断鼠标同时离开两个div的思路及代码
May 31 Javascript
javascript轻量级模板引擎juicer使用指南
Jun 22 Javascript
常用的jquery模板插件——jQuery Boilerplate介绍
Sep 23 Javascript
JavaScript入门基础
Aug 12 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
Dec 08 Javascript
js倒计时抢购实例
Dec 20 Javascript
深入理解jquery中的事件与动画
May 24 Javascript
详解XMLHttpRequest(一)同步请求和异步请求
Sep 14 Javascript
原生js实现轮播图
Feb 27 Javascript
微信小程序scroll-view的滚动条设置实现
Mar 02 Javascript
JavaScript实现鼠标经过表格某行时此行变色
Nov 20 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 飞信好友免费短信API接口开源版
2010/07/22 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
分享一个我自己写的ToolTip提示插件(附源码)
2013/01/20 Javascript
在jQuery中 关于json空对象筛选替换
2013/04/15 Javascript
JavaScript使用cookie实现记住账号密码功能
2015/04/27 Javascript
浅谈setTimeout 与 setInterval
2015/06/23 Javascript
基于Bootstrap实现Material Design风格表单插件 附源码下载
2016/04/18 Javascript
全面解析JavaScript的Backbone.js框架中的Router路由
2016/05/05 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
2016/05/28 Javascript
JavaScript兼容浏览器FF/IE技巧
2016/08/14 Javascript
微信小程序 地图(map)实例详解
2016/11/16 Javascript
基于jquery实现的鼠标悬停提示案例
2016/12/11 Javascript
详解angularjs获取元素以及angular.element()用法
2017/07/25 Javascript
基于ExtJs在页面上window再调用Window的事件处理方法
2017/07/26 Javascript
详解webpack与SPA实践之开发环境搭建
2017/12/18 Javascript
JavaScript递归函数解“汉诺塔”算法代码解析
2018/07/05 Javascript
JavaScript类的继承操作实例总结
2018/12/20 Javascript
echarts大屏字体自适应的方法步骤
2019/07/12 Javascript
js+canvas实现转盘效果(两个版本)
2020/09/13 Javascript
Python网络编程中urllib2模块的用法总结
2016/07/12 Python
Python操作MySQL数据库的方法
2018/06/20 Python
python实现多张图片拼接成大图
2019/01/15 Python
python用类实现文章敏感词的过滤方法示例
2019/10/27 Python
Python 开发工具PyCharm安装教程图文详解(新手必看)
2020/02/28 Python
Bluebella美国官网:英国性感内衣品牌
2018/10/04 全球购物
Pharmacy Online中文直邮网站:澳洲大型药房
2020/06/27 全球购物
Hashtable 添加内容的方式有哪几种,有什么区别?
2012/04/08 面试题
测绘工程本科生求职信
2013/10/10 职场文书
集团薪酬管理制度
2014/01/13 职场文书
吃空饷专项治理工作实施方案
2014/03/04 职场文书
2014三八妇女节活动总结范文四篇
2014/03/09 职场文书
创先争优承诺书范文
2014/03/31 职场文书
整顿机关作风心得体会
2014/09/10 职场文书
个人四风问题对照检查材料
2014/09/26 职场文书
2015年公务员个人工作总结
2015/04/24 职场文书
监护人证明
2015/06/19 职场文书