uniapp 验证码输入框 20240411

uniapp 验证码输入框

经常会有这样的需求,验证码只能输入数字,自动跳转到下一个数字位置,然后删除时自动跳转到上一个位置。

比如说需要输入6位数字的验证码,起初是打算用6个输入框来做,然后每个输入框有两个属性来控制,value和isFocus, 用来控制当前值以及当前框是不是获得焦点

不过这个在微信(安卓)端,由于焦点切换,数字键盘会有收起和弹出的动作,用起来就会闪动,网上有大神说只用一个input框来做,基于这个思路尝试了一下,个人觉得确实好用,希望对你也有用

先来个图

在这里插入图片描述

代码在这里


<template>
	<view class="container">
		<view class="sub-title">
			<text>验证码</text>
		</view>
		<view class="yy">
			<view class="desc">验证码已发送至您尾号{{phoneNumber.slice(-4)}}的手机号</view>
			<view class="outer">
				<view class="wrap">
					<view v-for="(item, key) in code" :key="key" class="inner" @click="handleCodeClick(key)">
						<view class="item">
							{{item.num}}
						</view>
					</view>
					<input v-if="inputFocus" type="number" inputmode="numeric" class="code-input" :focus="inputFocus"
						@blur="inputFocus=false" @input="inputFinish($event)" v-model="inputValue"
						:style="{left:activeIndex*width+'px'}" />
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	const keyCodeValue = {
		"48": "0",
		"49": "1",
		"50": "2",
		"51": "3",
		"52": "4",
		"53": "5",
		"54": "6",
		"55": "7",
		"56": "8",
		"57": "9"
	}

	export default {
		data() {
			return {
				phoneNumber: "13800000000",
				width: 60,
				activeIndex: 0,
				inputValue: '',
				inputFocus: false,
				code: [{
						num: '',
					},
					{
						num: '',
					},
					{
						num: '',
					},
					{
						num: '',
					},
					{
						num: '',
					},
					{
						num: '',
					},
				],
			}
		},
		methods: {
			handleConfirm() {
				const str = this.code.map(({
					num
				}) => num).join("")
				if (str.length !== 6) {
					return this.$modal.msg("请输入完整验证码");
				}
				this.$emit("callback", str)
			},
			handleCodeClick(index) {
				this.code[index].num = ""
				this.activeIndex = index
				this.inputFocus = true
			},
			inputFinish(e) {
				const index = this.activeIndex
				const {
					keyCode,
					value
				} = e.detail;
				if (keyCode === 8) {
					if (this.code[index]) this.code[index].num = '';
					if (index > 0) {
						this.code[index - 1].num = ''
						this.activeIndex--
					}
					return;
				}
				const v = keyCodeValue[keyCode]
				if (v) {
					this.code[index].num = v
				} else {
					this.code[index].num = ''
					return;
				}
				if (index + 1 == this.code.length) {
					this.activeIndex = -20
					this.inputFocus = false
				} else {
					this.activeIndex++
				}
				this.$nextTick(() => {
					this.inputValue = ""
					if (this.code[this.activeIndex]) {
						this.code[this.activeIndex].num = ""
					}
				})
			},
			 
		}
	}
</script>

<style lang="scss" scoped>
	.container {
		width: 750rpx;
		background: #FFFFFF;
		border-radius: 40rpx 40rpx 0rpx 0rpx;
		opacity: 1;
		overflow: hidden;
		padding: 200rpx 0;
	}

	.yy {
		text-align: center;
		.desc {
			padding-top: 40rpx;
		}

		.wrap {
			display: flex;
			align-items: center;
			margin-top: 50rpx;
			position: relative;

			.item {
				width: 50px;
				height: 50px;
				line-height: 50px;
				background-color: #eee;
				border-radius: 5px;
			}

			.inner {
				padding: 0px 5px;
				box-sizing: border-box;
			}

			.code-input {
				position: absolute;
				top: 0;
				width: 60px;
				height: 50px;
				line-height: 50px;
				// background-color: #eee;
				border-radius: 5px;
				// border: 1px solid red;
				box-sizing: border-box;
				z-index: 3;
			}
		}
	}


	.sub-title {
		height: 48rpx;
		font-size: 34rpx;
		font-weight: 500;
		color: rgba(0, 0, 0, 0.9);
		line-height: 40rpx;
		position: relative;
		text-align: center;
		padding-top: 40rpx;
	}
 
	.outer {
		display: flex;
		justify-content: center;
		align-items: center;
	}
</style>
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值