Vue如何实现验证码输入交互

2025-05-27 0 38

最近做一个H5的页面,里面有个输入验证码交互,就是移动端比较常见的那种验证码输入交互。就是那种,对,就是那种,一个数字一个下划线,移动端非常常见的那种验证码交互。实现过程中主要参考了美团外卖安卓端的具体交互。

应用到项目中的效果如下。

一般操作:

Vue如何实现验证码输入交互

粘贴效果:

Vue如何实现验证码输入交互

方案选择

方案1:调整文字的间距
设置 input 的 letter-spacing 属性,我们就可以让验证码之间有足够大的空隙,然后再把底线改为有间隔的多个线段貌似就可以了。

然而,这里会有一个问题。就是光标总是会在数字的左边,而我们希望的是输入后的数字的中心位于原来光标的位置。最终我放弃了这个方案。

显然,这个方案并不合适。

方案2:使用多个 input
这就是我使用的方式,也是接下来我要详细讲解的方案。主要原理是:使用多个 input 元素,每个 input 只能输入一个数字。当通过 input 事件监测到字符输入时,自动将焦点对焦到下一个 input 元素。

当然我们还要实现点击任何一个输入框时,将焦点移动到第一个value为空的input上。另外,点击退格键时,也要进行焦点的改变。

测试后后发现,焦点的移动,不会导致移动端键盘的收起。最终我就决定使用这个方案了。

代码实现
在线示例:https://codepen.io/F-star/pen/dyyeZaN

HTML:

?

1

2

3

4

5

6

7

8

9

10

11

12

13
<div id="app">

<div class="captcha">

<input v-for="(c, index) in ct" :key="index"

type="number" v-model="ct[index]" ref="input"

:style="{borderBottomColor: index <= cIndex ? '#333' : ''}"

@input="e => {onInput(e.target.value, index)}"

@keydown.delete="e=>{onKeydown(e.target.value, index)}"

@focus="onFocus"

:disabled="loading"

>

</div>

<p>{{msg}}</p>

</div>

CSS:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24
.captcha {

display: flex;

justify-content: center;

margin-top: 40px;

}

input {

margin-right: 20px;

width: 45px;

text-align: center;

border: none;

border-bottom: 1px solid #eee;

font-size: 24px;

outline: none;

}

input:last-of-type {

margin-right: 0;

}

input:disabled {

color: #000;

background-color: #fff;

}

.msg {

text-align: center;

}

JS:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93
var Main = {

data() {

return {

ct: ['', '', '', '', '', ''],

loading: false,

msg: '',

}

},

computed: {

ctSize() {

return this.ct.length;

},

cIndex() {

let i = this.ct.findIndex(item => item === '');

i = (i + this.ctSize) % this.ctSize;

return i;

},

lastCode() {

return this.ct[this.ctSize - 1];

}

},

watch: {

cIndex() {

this.resetCaret();

},

lastCode(val) {

if (val) {

console.log('this.ctSize', this.ctSize)

this.$refs.input[this.ctSize - 1].blur();

this.sendCaptcha();

}

}

},

mounted() {

this.resetCaret();

},

methods: {

onInput(val, index) {

this.msg = ''

val = val.replace(/\\s/g, '');

if (index == this.ctSize - 1) {

this.ct[this.ctSize - 1] = val[0]; // 最后一个码,只允许输入一个字符。

} else if(val.length > 1) {

let i = index;

for (i = index; i < this.ctSize && i - index < val.length; i++) {

this.ct[i] = val[i];

}

this.resetCaret();

}

},

// 重置光标位置。

resetCaret() {

this.$refs.input[this.ctSize-1].focus();

},

onFocus() {

// 监听 focus 事件,将光标重定位到“第一个空白符的位置”。

let index = this.ct.findIndex(item => item === '');

index = (index + this.ctSize) % this.ctSize;

console.log(this.$refs.input)

this.$refs.input[index].focus();

},

onKeydown(val, index) {

if (val === '') {

// 删除上一个input里的值,并对其focus。

if (index > 0) {

this.ct[index - 1] = '';

this.$refs.input[index - 1].focus();

}

}

},

sendCaptcha() {

console.log();

this.msg = `发送验证码到服务器:${this.ct.join('')}`;

// 此时无法操作 input。。

this.loading = true;

setTimeout(() => {

this.msg = ('验证码错误')

this.loading = false;

this.$nextTick(() => {

this.reset();

})

}, 3000)

},

reset() {

// 重置。一般是验证码错误时触发。

this.ct = this.ct.map(item => '');

this.resetCaret();

}

}

}

var Ctor = Vue.extend(Main)

new Ctor().$mount('#app')

原理

创建多个 input 元素,对这些 input 都绑定 focus 事件。一旦触发该事件,我们会把焦点移动到从左往右第一个 value 为空字符的 input 上。所以在初始状态时,点击最右边的 input,光标还是会跑到最左边的 input。

然后我们给这些 input 绑定 input 事件,监听输入字符。当输入后的字符不为空字符,我们会和 focus 事件一样,重定位下一个需要聚焦的 input。如果输入的是多个字符(一般是是粘贴的缘故),就会把多出来的字符一个一个按顺序填入到后面的 input 中,然后才重定位光标。这样,我们就实现了一个个输入数字和粘贴短信验证码(一次性输入多个数字)的交互。

最后我们还要处理退格行为,需要给所有 input 绑定 keydown 事件。当按下的为退格键,且当前 input 的 value 为空时,清空上一个 input 里的数据,并聚焦到上一个 input 上。

对了,验证码输入错误后,需要清除所有 input 的数据,并把焦点移动到第一个 input 上。

总结
原理并不复,只是实现起来有点繁琐。

我这个方案没有进行浏览器兼容,请大家在经过充分的测试后再行使用。

如果可以的话,我还是推荐简单的一个输入框方案,而不是选择这种花里胡哨的交互。简单稳妥的实现维护简单,也不会有太多意想不到的状况。因为验证码输入这里如果在某些浏览器上无法正确操作,对转化率还是有很大影响的。

以上就是Vue如何实现验证码输入交互的详细内容,更多关于vue 验证码输入交互的资料请关注快网idc其它相关文章!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Vue如何实现验证码输入交互 https://www.kuaiidc.com/77306.html

相关文章

发表评论
暂无评论