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 相关文章推荐
arguments对象
Nov 20 Javascript
一些经常会用到的Javascript检测函数
May 31 Javascript
js克隆对象、数组的常用方法介绍
Sep 26 Javascript
如何让浏览器支持jquery ajax load 前进、后退功能
Jun 12 Javascript
DOM节点删除函数removeChild()用法实例
Jan 12 Javascript
Bootstrap精简教程中秋大放送
Sep 15 Javascript
Vue.JS入门教程之处理表单
Dec 01 Javascript
微信小程序 解析网页内容详解及实例
Feb 22 Javascript
vue-router 权限控制的示例代码
Sep 21 Javascript
Vue组件之全局组件与局部组件的使用详解
Oct 09 Javascript
vue+web端仿微信网页版聊天室功能
Apr 30 Javascript
如何对react hooks进行单元测试的方法
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显示MySQL数据的三种方法
2008/06/05 PHP
深入理解PHP之数组(遍历顺序)  Laruence原创
2012/06/13 PHP
php获取QQ头像并显示的方法
2014/12/23 PHP
源码分析 Laravel 重复执行同一个队列任务的原因
2017/12/25 PHP
YII框架http缓存操作示例
2019/04/29 PHP
尽可能写&quot;友好&quot;的&quot;Javascript&quot;代码
2007/01/09 Javascript
ExtJs使用总结(非常详细)
2012/03/22 Javascript
javascript自然分类法算法实现代码
2013/10/11 Javascript
jquery实现邮箱自动补全功能示例分享
2014/02/17 Javascript
前端轻量级MVC框架CanJS详解
2014/09/26 Javascript
JS检测是否可以访问公网服务器功能代码
2017/06/19 Javascript
Angular6 用户自定义标签开发的实现方法
2019/01/08 Javascript
layui.use模块外部使用其内部定义的js封装函数方法
2019/09/16 Javascript
微信小程序反编译的实现
2020/12/10 Javascript
[00:52]黑暗之门更新 新英雄孽主驾临DOTA2
2016/08/24 DOTA
python处理文本文件并生成指定格式的文件
2014/07/31 Python
python 异常处理总结
2016/10/18 Python
python Django 创建应用过程图示详解
2019/07/29 Python
Pytorch之contiguous的用法
2019/12/31 Python
python使用多线程+socket实现端口扫描
2020/05/28 Python
matplotlib 范围选区(SpanSelector)的使用
2021/02/24 Python
amazeui页面分析之登录页面的示例代码
2020/08/25 HTML / CSS
中职生自我鉴定范文
2013/10/03 职场文书
解除劳动合同协议书
2014/04/14 职场文书
党员四风自我剖析材料思想汇报
2014/09/13 职场文书
工伤事故赔偿协议书
2014/10/27 职场文书
2014年优质护理服务工作总结
2014/11/14 职场文书
小学教师岗位职责
2015/04/02 职场文书
2015年保险公司个人工作总结
2015/05/22 职场文书
2015婚礼主持词开场白
2015/05/28 职场文书
成绩单家长意见
2015/06/03 职场文书
2015年教务主任工作总结
2015/07/22 职场文书
创业计划书之奶茶店开店方案范本!
2019/08/06 职场文书
Vue过滤器(filter)实现及应用场景详解
2021/06/15 Vue.js
Pandas 稀疏数据结构的实现
2021/07/25 Python
漫画《尖帽子的魔法工坊》宣布动画化
2022/04/06 日漫