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 相关文章推荐
ext 同步和异步示例代码
Sep 18 Javascript
js语法学习之判断一个对象是否为数组
May 13 Javascript
JavaScript获得页面base标签中url的方法
Apr 03 Javascript
jquery模拟进度条实现方法
Aug 03 Javascript
基于javascript实现图片懒加载
Jan 05 Javascript
Angularjs material 实现搜索框功能
Mar 08 Javascript
javascript中this指向详解
Apr 23 Javascript
浅析jquery unbind()方法移除元素绑定的事件
May 24 Javascript
vue2.0多条件搜索组件使用详解
Mar 26 Javascript
js如何编写简单的ajax方法库
Aug 02 Javascript
AngularJS路由删除#符号解决的办法
Sep 28 Javascript
vue-cli+webpack项目 修改项目名称的方法
Feb 28 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数据序列化测试实例详解
2017/08/12 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
2018/08/20 PHP
解决windows上php xdebug 无法调试的问题
2020/02/19 PHP
jQuery选择器的工作原理和优化分析
2011/07/25 Javascript
jquery中trigger()无法触发hover事件的解决方法
2015/05/07 Javascript
使用javascript将时间转换成今天,昨天,前天等格式
2015/06/25 Javascript
实现音乐播放器的代码(html5+css3+jquery)
2015/08/04 Javascript
jQuery绑定自定义事件的魔法升级版
2016/06/30 Javascript
Javascript中级语法快速入手
2016/07/30 Javascript
Ajax的概述与实现过程
2016/11/18 Javascript
jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
2016/12/30 Javascript
jQuery模拟下拉框选择对应菜单的内容
2017/03/07 Javascript
Vue学习笔记进阶篇之vue-cli安装及介绍
2017/07/18 Javascript
vue父组件向子组件动态传值的两种方法
2017/11/11 Javascript
vue实现树形菜单效果
2018/03/19 Javascript
微信小程序自定义对话框弹出和隐藏动画
2018/07/19 Javascript
jQuery实现动态生成年月日级联下拉列表示例
2019/05/11 jQuery
微信小程序实现搜索功能并跳转搜索结果页面
2019/05/18 Javascript
vue实现多组关键词对应高亮显示功能
2019/07/25 Javascript
javascript设计模式之迭代器模式
2020/01/30 Javascript
vue+iview实现文件上传
2020/11/17 Vue.js
[05:31]DOTA2英雄梦之声_第08期_莉娜
2014/06/23 DOTA
python实现比较类的两个instance(对象)是否相等的方法分析
2019/06/26 Python
python django下载大的csv文件实现方法分析
2019/07/19 Python
python操作excel让工作自动化
2019/08/09 Python
python+selenium select下拉选择框定位处理方法
2019/08/24 Python
python库matplotlib绘制坐标图
2019/10/18 Python
CSS3制作hover下划线动画
2017/03/27 HTML / CSS
入党自我鉴定范文
2013/10/04 职场文书
技术岗位竞聘演讲稿
2014/05/16 职场文书
企业环保标语
2014/06/10 职场文书
大班下学期个人总结
2015/02/13 职场文书
详解如何修改nginx的默认端口
2021/03/31 Servers
python编程项目中线上问题排查与解决
2021/11/01 Python
关于的python五子棋的算法
2022/05/02 Python
macos系统如何实现微信双开? mac登录两个微信以上微信的技巧
2022/07/23 数码科技