前言

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

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

正文

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

Dom 部分

<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 部分

<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 部分

<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>

总结

效果、代码如上,话要少叙,若对您有用请留下您的足迹,若写的有瑕疵也请不吝指教。 如上代码可以根据个人需求进行优化,我没有发起请求,方法已经建立了也已经注明,把自己的请求加入即可。 如果有不懂的欢迎留言交流。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐