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 相关文章推荐
获取DOM对象的几种扩展及简写
Oct 09 Javascript
一个通过script自定义属性传递配置参数的方法
Sep 15 Javascript
使用jQuery简单实现模拟浏览器搜索功能
Dec 21 Javascript
jquery动态导航插件dynamicNav用法实例分析
Sep 06 Javascript
JavaScript通过filereader接口读取文件
May 10 Javascript
vue实现app页面切换动画效果实例
May 23 Javascript
ES6正则表达式扩展笔记
Jul 25 Javascript
javascript计算对象长度的方法
Oct 25 Javascript
webpack-url-loader 解决项目中图片打包路径问题
Feb 15 Javascript
vue.config.js常用配置详解
Nov 14 Javascript
Jquery让form表单异步提交代码实现
Nov 14 jQuery
了不起的11个JavaScript代码重构最佳实践小结
Jan 11 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
上传文件先创建目录 再上传到目录里面去
2010/12/29 PHP
PHP 实现explort() 功能的详解
2013/06/20 PHP
PHP之正则表达式捕获组与非捕获组(详解)
2015/07/29 PHP
php析构函数的简单使用说明
2015/08/24 PHP
php实现的读取CSV文件函数示例
2017/02/07 PHP
PHP支付宝当面付2.0代码
2018/12/21 PHP
php探针不显示内存解决方法
2019/09/17 PHP
TP框架实现上传一张图片和批量上传图片的方法分析
2020/04/23 PHP
js字符串转换成xml对象并使用技巧解读
2013/04/18 Javascript
Jquery多选下拉列表插件jquery multiselect功能介绍及使用
2013/05/24 Javascript
巧用jquery解决下拉菜单被Div遮挡的相关问题
2014/02/13 Javascript
jquery ajaxSubmit 异步提交的简单实现
2014/02/28 Javascript
JavaScript、tab切换完整版(自动切换、鼠标移入停止、移开运行)
2016/01/05 Javascript
javascript实现表单验证
2016/01/29 Javascript
特殊日期提示功能的实现方法
2016/06/16 Javascript
JS实战篇之收缩菜单表单布局
2016/12/10 Javascript
js定时器实现倒计时效果
2017/11/05 Javascript
基于vue监听滚动事件实现锚点链接平滑滚动的方法
2018/01/17 Javascript
JS无限级导航菜单实现方法
2019/01/05 Javascript
2020淘宝618理想生活列车自动领喵币js脚本的代码
2020/06/02 Javascript
iview实现动态表单和自定义验证时间段重叠
2021/01/10 Javascript
[00:35]可解锁地面特效
2018/12/20 DOTA
Tornado服务器中绑定域名、虚拟主机的方法
2014/08/22 Python
python操作文件的参数整理
2019/06/11 Python
Python Sqlalchemy如何实现select for update
2020/10/12 Python
Hotter Shoes英国官网:英伦风格,舒适的鞋子
2017/12/28 全球购物
管理学专业个人求职信范文
2013/09/21 职场文书
行政办公员自我评价分享
2013/12/14 职场文书
上课说话检讨书大全
2014/01/22 职场文书
幼儿园开学寄语
2014/04/03 职场文书
运动会口号16字
2014/06/07 职场文书
亚运会口号
2014/06/20 职场文书
授权委托书样本及填写说明
2014/09/19 职场文书
2014年控辍保学工作总结
2014/12/08 职场文书
人力资源部工作计划
2019/05/14 职场文书
python模块与C和C++动态库相互调用实现过程示例
2021/11/02 Python