要实现的功能:

完全和单输入框一样的操作,甚至可以插入覆盖:

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>

<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() {if (this.code && Array.isArray(this.code) && this.code.length === 6) {return this.code;} else if (/^d{6}$/.test(this.code.toString())) {return this.code.toString().split('');} else if (this.pasteResult.length === 6) {return this.pasteResult;} else {return new Array(6);}}},methods: {// 解决一个输入框输入多个字符inputEvent(e) {var index = e.target.dataset.index * 1;var el = e.target;el.value = el.value.replace(/Digit|Numpad/i, '').replace(/1/g, '').slice(0, 1);this.$set(this.input, index, el.value)},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;// 解决输入e的问题el.value = el.value.replace(/Digit|Numpad/i, '').replace(/1/g, '').slice(0, 1);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);this.pasteResult = [];} else {// 如果粘贴内容不合规,清除所有内容this.input[0] = new Array(6)}})}},mounted() {// 等待dom渲染完成,在执行focus,否则无法获取到焦点this.$nextTick(() => {this.$refs.firstinput.focus()})},}
</script>

如果你发现了bug,或者有优化空间,欢迎你的指正和建议。我会随时更新到原代码当中,分享给大家。

作者:jsoncode

链接:人类身份验证 - SegmentFault

来源:SegmentFault 思否社区

vue 实现动态增加输入框_vue实现一个6个输入框的验证码输入组件相关推荐

  1. Vue - 实现验证码输入组件

    效果图 功能分解 输入效果 自动换焦 如何删除 接收paste事件 数据先行 确定验证码位数 amout 储存验证码的数组 code 当前输入项的索引 currentIndex 布局 <temp ...

  2. Vue.js 动态组件 异步组件

    在动态组件上使用 keep-alive 我们之前曾经在一个多标签的界面中使用 is 特性来切换不同的组件: <component v-bind:is="currentTabCompon ...

  3. input输入框模拟验证码输入效果

    今天看到一个帖子,说到用input输入框模拟滴滴.摩拜等app验证码输入效果,提到了一个方案: 1.利用input来获得焦点,自动调用手机的数字键盘 2.实际将输入框用透明度隐藏 3.用label的f ...

  4. vue 不能响应set结构增加数据_Vue.set()动态的新增与修改数据,触发视图更新的方法...

    参数: target:要更改的数据源(可以是对象或者数组) key:要更改的具体数据(可以是字符串和数字) value :重新赋的值 用法:向响应式对象中添加一个属性,并确保这个新属性同样是响应式的, ...

  5. 弹出框动态增加input输入框

    欢迎关注微信公众号: 程序员小圈圈 原文首发于: www.zhangruibin.com 本文出自于: RebornChang的博客 转载请标明出处^_^ 弹出框动态增加input输入框 最近项目上有 ...

  6. vue动态增加商品属性

    vue+element ui实现动态增加商品sku 实现逻辑(循环遍历数组,通过push来增加属性,通过splice移出属性) html <div><el-row class=&qu ...

  7. Ant Design of Vue +TS 表单动态增加数据验证卧坑姿势

    文章目录 Update 20210601 Update 20210525 原文: 1.a-form的model 2.获取数据 源码 Update 20210601 今天做别的页面的时候发现又取不到数据 ...

  8. vue 移动端头像裁剪_vue头像上传裁剪组件_一个漂亮的Vue组件,用于图像裁剪和上传...

    vue头像上传裁剪组件 vue-image-crop-upload (vue-image-crop-upload) A beautiful vue component for image crop a ...

  9. 后盾网lavarel视频项目---vue实现动态添加和删除板块

    后盾网lavarel视频项目---vue实现动态添加和删除板块 一.总结 一句话总结: 原理就是:列表时根据vue中的videos变量中的元素来遍历的,初始时videos:[{title:'',pat ...

最新文章

  1. python快速编程答案-100+Python编程题带你快速上手(附答案)
  2. 牛客题霸 NC2 重排链表
  3. top统计mysql性能_mytop安装,使用mytop监控MySQL性能
  4. linux之gdb基本调试命令和使用总结
  5. 电脑无internet访问_电脑中的代理服务器怎么设置 代理服务器设置方法 - 操作系统...
  6. 华为防火墙查看日志命令_华为防火墙异常日志,请高手进来查看,跪谢
  7. 【链接】 一篇很好的有关卡特兰数的博文
  8. mysql 遍历json数据结构,mysql存储过程中遍历json数据
  9. 使用备份工具mysqldump备份数据库
  10. Android强大的控件——RecyclerView
  11. 基于matlab的车牌定位算法设计与实现,原创】基于matlab的汽车牌照识别系统设计与实现...
  12. 学习Python可以做什么工作?选哪些工作方向?
  13. 左手拿叉右手拿刀——话西餐
  14. Java基础361问第5问——equals和==的区别
  15. 英汉《营销学》常用词汇-1
  16. 2口kvm切换器使用方法简述
  17. html5绘制好看的时钟,利用纯html5绘制出来的一款非常漂亮的时钟
  18. android 电话回音消除,智能门铃中可视对讲的回音消除
  19. 用Nextcloud搭建个人网盘
  20. OpenCV系列之级联分类器 | 六十一

热门文章

  1. Spring boot配置文件占位符
  2. Mybatis查询日期范围
  3. Select控件可选可输入
  4. delphi tabsheet多标签自适应宽度_HTML 图像 img 标签
  5. 【2019暑假刷题笔记-STL绪论(二)】总结自《算法笔记》
  6. 海量数据下如何使用多线程的导出 Excel
  7. 太炫酷了!逼格高的键盘敲代码贼爽!包邮送到家!
  8. 【struts2+hibernate+spring项目实战】实现用户登录功能(ssh)
  9. 蓝桥杯-表达式计算(java)
  10. Java常用类之【Math类、Random类、System类、Runtime类】