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 相关文章推荐
js 幻灯片的实现
Dec 06 Javascript
TinyMCE提交AjaxForm获取不到数据的解决方法
Mar 05 Javascript
jquery实现的代替传统checkbox样式插件
Jun 19 Javascript
基于bootstrap3和jquery的分页插件
Jul 31 Javascript
Angular2从搭建环境到开发步骤详解
Oct 17 Javascript
AngularJS Select(选择框)使用详解
Jan 18 Javascript
BootStrap框架中的data-[ ]自定义属性理解(推荐)
Feb 14 Javascript
node.js实现登录注册页面
Apr 08 Javascript
js中自定义react数据验证组件实例详解
Oct 19 Javascript
Bootstrap 实现表格样式、表单布局的实例代码
Dec 09 Javascript
详解webpack打包vue项目之后生成的dist文件该怎么启动运行
Sep 06 Javascript
一篇文章带你使用Typescript封装一个Vue组件(简单易懂)
Jun 05 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入库和出库
2013/06/25 PHP
8个必备的PHP功能实例代码
2013/10/27 PHP
PHP获取文件夹内文件数的方法
2015/03/12 PHP
php显示指定目录下子目录的方法
2015/03/20 PHP
PHP处理会话函数大总结
2015/08/05 PHP
深入讲解PHP的Yii框架中的属性(Property)
2016/03/18 PHP
PHP+HTML+JavaScript+Css实现简单爬虫开发
2016/03/28 PHP
推荐10个超棒的jQuery工具提示插件
2011/10/11 Javascript
js实现动态添加、删除行、onkeyup表格求和示例
2013/08/18 Javascript
tangram框架响应式加载图片方法
2013/11/21 Javascript
jquery实现上下左右滑动的方法
2015/02/09 Javascript
jQuery实现鼠标划过展示大图的方法
2015/03/09 Javascript
JS实现的最简Table选项卡效果
2015/10/14 Javascript
JS实现字符串转日期并比较大小实例分析
2015/12/09 Javascript
浅析JavaScript中break、continue和return的区别
2016/11/30 Javascript
JS实现搜索关键词的智能提示功能
2017/07/07 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
2018/08/25 Javascript
vue 父组件通过v-model接收子组件的值的代码
2019/10/27 Javascript
JS中FormData类实现文件上传
2020/03/27 Javascript
JavaScript实现alert弹框效果
2020/11/19 Javascript
[01:32]TI奖金增速竟因它再创新高!DOTA2勇士令状不朽珍藏Ⅰ饰品欣赏
2018/05/18 DOTA
[40:31]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
django自带的server 让外网主机访问方法
2018/05/14 Python
解决Django部署设置Debug=False时xadmin后台管理系统样式丢失
2020/04/07 Python
HTML5 video视频字幕的使用和制作方法
2018/05/03 HTML / CSS
浅析HTML5 Landmark
2020/09/11 HTML / CSS
医务人员自我评价
2014/01/26 职场文书
公司总经理工作职责管理办法
2014/02/28 职场文书
天网工程实施方案
2014/03/26 职场文书
工作检讨书大全
2015/01/26 职场文书
仓库管理员岗位职责
2015/02/03 职场文书
2015年感恩父亲节活动策划方案
2015/05/05 职场文书
2015年小学美术工作总结
2015/05/25 职场文书
《天净沙·秋思》教学反思三篇
2019/11/02 职场文书
css实现左上角飘带效果的完整代码
2022/03/18 HTML / CSS
教你使用Jenkins集成Harbor自动发布镜像
2022/04/03 Servers