uniapp 实现验证码输入框

前言

在实现页面的时候验证码输入的场景是比较常见的,如果使用一些前端 UI 组件会有这样的组件,可一些情况下需要自己去实现。比如小程序,如果过多依赖组件库,在一个小程序中仅使用一个组件库还好,引用组件多了会受到包大小的限制打包不了,所以一些效果和样式能自己写尽量自己写(仅限简单的,不建议重复造车)。

我们今天要分享的验证码输入框就是比较简单的一种实现,若为了它去引一个组件到工程中是不值得的,占空间。所以今天我动手实现了一个,供大家借鉴参考。

正文

话不多说,我们先看效果:


Dom 部分

查看 HTML 代码
<view class="phone_code">
    <text class="phone_code_label">验证码已发送至</text>
    <view class="phone_code_count">
        <text class="phone_code_count_new">{{ newPhone }}</text>
        <view v-if="isReget" class="phone_code_count_reget">
            <button plain="true" type="warn" size="mini" @click="getCode">重新获取</button>
        </view>  
        <text v-else class="phone_code_count_down">获取验证码<text>{{count}}</text>s</text>
    </view>
    <view class="phone_code_single">
        <input class="phone_code_single_cinput" 
            adjust-position="false" 
            auto-blur="true" 
            @blur="codeNumBlurFun" 
            @input="codeNumInputFun" 
            :focus="focus" 
            v-model="code" 
            type="number" 
            maxlength="6"/>
        <view class="phone_code_single_codeinput">
            <view v-for="(item,index) in 6" 
                :key="index" 
                @click="codefocusFun(index)" 
                :style="(index == code.length? 'background-color:#FEF2F2;':'color: #313131;background-color:#eee')">
                {{code[index]}}
            </view>		
        </view> 
    </view>
    <button :disabled="isCode" class="btn" type="warn" @click="submitFun()">确定</button>
 </view>

JS 部分

查看 JavaScript 代码
<script> 
	export default {
		data() {
			return {
                                newPhone: "167****8898", // 当前显示电话
                                isReget: false,  // 判断是否显示 ‘重新获取’按钮    
				timer: null,   // 定时器
				count: 60,  // 时间
				code: "",  // 验证码  
				focus: true,   // 焦点
                                isCode:true  // ‘确定’按钮是否禁用
			} 
		},
		onLoad(options) {
 			this.getTimer() // 开启定时器
			this.getCode() // 获取验证码 
		},
		watch:{
			count(val){
				if(val==0){
					this.isReget = true 
					clearInterval(this.timer)
				}
			},
		},
		methods: {
                        /**
			 * AUTHOR: 单乘风
			 * DESC: 定时器  
			 * */ 
			getTimer(){
				this.timer = setInterval(()=>{
					if(this.count==0){
						clearInterval(this.timer)
						uni.navigateBack({delta: 1})
						return
					}
					this.count-- 
				}, 1000)
			},
			
			/**
			 * AUTHOR: 单乘风
			 * DESC: 获取验证码   
			 * */
			getCode(){
				console.log("获取验证码", this.newPhone)
				if(this.count==0){
					this.count = 60 
					this.isReget = false 
					this.getTimer()
				}
			},
			/**
			 * AUTHOR: 单乘风
			 * DESC: 输入框输入事件 
			 * */ 
			codeNumInputFun(e){ 
				let val = e.detail.value 
				this.code = val 
				if(val.length==6) this.isCode = false
				else this.isCode = true 
			},
			/**
			 * AUTHOR: 单乘风
			 * DESC: 输入框失去焦点事件 
			 * */ 
			codeNumBlurFun(e){
				let val = e.detail.value 
				this.focus = false
				if(val.length==6) this.isCode = false
				else this.isCode = true 
			},
			/**
			 * AUTHOR: 单乘风
			 * DESC: 输入框点击事件
			 * @param {Number} index 当前点击框索引
			 * */ 
			codefocusFun(index){ 
				this.focus = true 
			},
                        /**
			 * AUTHOR: 单乘风
			 * DESC: 按钮点击事件
			 * */ 
			submitFun(){  
				console.log("确认更换手机号")
			},
		}
	}
</script>

SCSS 部分

查看 CSS 代码
<style lang="scss" scoped>
 .phone{
        background-color: #FFF;
        width: 100vw;
        height: 100vh; 
	&_code{
		padding: 30rpx;
		&_label{
			font-size: 30rpx;
			color: #999;
		}
		&_count{
			margin-top: 30rpx;
			display: flex;
			flex-direction: row;
			justify-content: space-between; 
			align-items: center;
			height: 100rpx;
			&_new{
				color: #e64340;
				font-size: 38rpx;
				font-weight: bold; 
			}
			&_down{
				border: 1rpx solid #eee;
				border-radius: 10rpx; 
				color: #999;
				height: 60rpx;
				line-height: 60rpx;
				padding: 0 20rpx;
				text{
					margin-left: 10rpx;
				}
			} 
		}
		&_single{
			margin-top: 30rpx; 
			&_cinput{
				position: fixed;
				left: -100rpx;
				width: 50rpx;
				height: 50rpx;
			}
			&_codeinput{
				margin: auto;
				width: 650rpx;
				height: 100rpx;
				display: flex;
			}
			 
			&_codeinput>view {
				margin-top: 5rpx;
				margin-left: 15rpx;
				width: 86rpx;
				height: 86rpx;
				line-height: 86rpx;
				font-size: 60rpx;
				font-weight: bold;
				color: #313131;
				text-align: center;
				border-radius: 10rpx;
			}
		 
			&_codeinput>view:nth-child(1) {
				margin-left: 0rpx;
			} 
		}
	}
}
</style>

总结

效果、代码如上,话要少叙,若对您有用请留下您的足迹,若写的有瑕疵也请不吝指教。

如上代码可以根据个人需求进行优化,我没有发起请求,方法已经建立了也已经注明,把自己的请求加入即可。

如果有不懂的欢迎留言交流。

posted @ 2023-02-22 09:16  Chengo  阅读(455)  评论(0编辑  收藏  举报