vue2之簡易的pc端短信驗證碼的問題

導言

昨天在作項目的時候,遇到了一個小小的問題(大神或大佬)能夠略過此處,給剛剛入門或者想學習vue的朋友準備的小小的福利。

效果圖片以下

<提示語部分不要在乎(非重點部分)>
簡單說下佈局(採用的是vue的element ui的ui框架)進行佈局操做的
子組件模板部分以下(code部分是很基礎的)
<template>
    <div class="forget">
        <el-dialog title="修改新密碼" :visible.sync="dialog.visible"
        :close-on-click-modal="false"
                   :close-on-press-escape="false"
        >
            <el-form :model="dialog.ruleForm" status-icon :rules="rules" :ref="dialog.ruleForms"

                     label-width="100px" class="demo-ruleForm">
                <el-form-item label="手機號碼" prop="phone" required>
                    <el-input type="text" v-model.number="dialog.ruleForm.phone" autocomplete="off"
                              :clearable="true"
                    ></el-input>
                </el-form-item>
                <el-form-item label="手機驗證碼"prop="code" required>
                    <div class="send-code">
                        <el-input type="text" v-model="dialog.ruleForm.code" autocomplete="off"
                                  maxlength="6"
                                  show-word-limit
                                  :clearable="true"
                        ></el-input>
                        <el-link

                                :style="{color:dialog.ruleForm.phone.toString().length===11?'#222':'#999'}"
                                type="info"  :underline="false"
                                :disabled="getDisabled"
                                @click="sendCode({ phone:dialog.ruleForm.phone,sendCode:dialog.ruleForm.sendCode })"
                        >{{dialog.ruleForm.sendCode}}</el-link>
                    </div>
                </el-form-item>
                <el-form-item label="新密碼"  prop="newPwd" required>
                    <el-input  :clearable="true" type="password" v-model="dialog.ruleForm.newPwd"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="cancel">取 消</el-button>
                <el-button type="primary" @click="determine(dialog.ruleForms)"
                           :loading="dialog.ruleForm.loading"
                >{{dialog.ruleForm.loadingText}}</el-button>
            </div>
        </el-dialog>
    </div>
</template>
複製代碼
子組件邏輯部分以下(code部分是很基礎的)
在@/utils/validate.js中的使用正則代碼
// 驗證手機號碼
export const validatPhone = /^(^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$)|(13[0-9]|14[5-9]|15[012356789]|166|17[0-8]|18[0-9]|19[8-9])[0-9]{8}$/

//驗證密碼
export const validatePassword = /^(?=.*\d)(?=.*[a-zA-Z]).{5,20}$/
複製代碼
<script>
    import {validatPhone,validatePassword} from '@/utils/validate'
    export default {
        props:{
            dialog:{
                type:Object,
                default: {}
            },
        },
        name: "Forget",
        data(){
        // 使用正則進行驗證手機號碼
            const validatePhone = (rule, value, callback) => {
                if (!value) {
                    return callback(new Error('請輸入手機號碼'));
                }
                else {
                    if (!validatPhone.test(value)) {
                        callback(new Error('請輸入手機號碼'));
                        return
                    }
                    callback();
                }
            };
            // 使用進行驗證手機驗證碼
            const validateCode = (rule, value, callback) => {
                if (value === '') {
                    return callback(new Error('請輸入驗證碼'));
                } else {
                //真正環境請修改爲本身的邏輯便可
                    if (this.dialog.ruleForm.code !== '123456') {
                        callback(new Error('驗證碼失誤,請從新輸入'))
                        // this.dialog.ruleForm.code = ''
                        return
                    }
                    callback();
                }
            };
            // 使用正則進行驗證密碼
            const validatenewPwd = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('請輸入密碼'));
                    return
                } else if (!validatePassword.test(value)) {
                    return callback(new Error('新密碼不合法'));
                } else {
                    callback();
                }
            };
            return {
                rules:{ //驗證表單元素中的規則
                    phone:[
                        { validator: validatePhone, trigger: ['blur','change'] }
                    ],
                    code:[
                        { validator: validateCode, trigger: ['blur','change'] }
                    ],
                    newPwd:[
                        { validator: validatenewPwd, trigger: ['blur','change'] }
                    ],
                },
                timer: null//操做定時器

            }
        },
        computed:{
            //getDisabled() 當手機號碼的長度等於11位和點擊驗證碼狀態爲false時,則能夠進行倒計時操做 
            getDisabled(){
                let phone= this.dialog.ruleForm.phone
                const isChick = this.dialog.ruleForm.isChick
                if(phone.toString().length === 11 && isChick ===false){
                   return false
                }
                else {
                    // this.dialog.ruleForm.disabled = true
                    return  true
                }

            }
        },
        methods:{
            // 發送驗證碼
            sendCode(opt){
                this.$emit('sendCode',opt)
            },
            // 點擊取消按鈕時觸發
            cancel(){
                this.$emit('cancel')
            },
            // 點擊肯定按鈕時觸發
            determine(resf){

                this.$refs[resf].validate((valid) => {
                    if (valid) {
                        this.$emit('determine',resf)
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });

            },
        }
    }
</script>

複製代碼
子組件邏輯部分以下(code部分是很基礎的)
<style scoped lang="scss">
    .forget{
        /deep/ .el-dialog__wrapper{
            .el-dialog{
                max-width: 500px;
                .el-dialog__header{
                    text-align: center;
                }
            }
            .demo-ruleForm{
                .el-form-item__content{
                    max-width:100%
                }
            }
            .el-dialog__body{
                .el-form-item{
                    text-align: center;
                }
            }
        }
        .send-code{
            display: flex;flex: 1;justify-content: space-evenly;
            /deep/ .el-input{
                margin-right: 12px
            }
            /deep/ .el-link{
                white-space: nowrap;
                display: inline-block;
                line-height: 1;
                cursor: pointer;
                background: #fff;
                border: 1px solid #dcdfe6;
                color: #606266;
                -webkit-appearance: none;
                text-align: center;
                box-sizing: border-box;
                outline: none;
                margin: 0;
                transition: .1s;
                font-weight: 500;
                -moz-user-select: none;
                -webkit-user-select: none;
                -ms-user-select: none;
                padding: 12px 10px;
                font-size: 14px;
                border-radius: 4px;
            }
        }
        .dialog-footer{
            display: flex;
            flex: 1;
            justify-content: center;
            /deep/ .el-button{
                flex: 0 0 40%;
            }
        }
    }
</style>
複製代碼
父組件中的模板部分
<template>
        <forget :dialog="dialog"@cancel="dialog.visible= false" @determine="determine" @sendCode="sendCode"></forget>

</template>



複製代碼
爲何須要使用set這個api方法呢
以下截圖

能夠學習下這個連接的使用set的例子
全局變量globals.js文件
[vue-set]的文檔(cn.vuejs.org/v2/api/#Vue…)
說明(*****向響應式對象中添加一個屬性,並確保這個新屬性一樣是響應式的,且觸發視圖更新。)
export default {
    //判斷是否點擊了
    isChick(data,key='disabled',count=0){
        data[key] =true
        if(count<=0){
            data[key] =false
        }
    },
    //此處是重點 使用的vue官網給的api方法
    [vue-set](https://cn.vuejs.org/v2/api/#Vue-set)
    sendCode(self,name,k,v){
        self.$set(name,k,v)
    }
}


複製代碼
父組件中的邏輯部分
<script>
 export default {
     data() {
            return {
            //  顯示子組件修改密碼的對象變量
                      dialog: {
                    visible: false, //是否顯示 
                    ruleForms: 'ruleForms', //點擊按鈕後,須要操做的refs(也就是dom元素)
                    ruleForm: {   //所須要進行在表單中操做的部分
                        phone: '',
                        newPwd: '',
                        code: '',
                        sendCode: '發送驗證碼',
                        disabled: false,
                        isChick:false,
                        loading: false,
                        loadingText: '確 定'
                    },
                    
                }, 
                //倒計時60秒
                 timeCount:60
            }
         
     },
     methods:{
            //重點部分
            sendCode60s(self,opt){
                let count=self.timeCount;
                const ruleForm = self[opt.dialog][opt.ruleForm]
                self.timer = setInterval(()=>{
                    //這個按鈕是
                    self.$globals.isChick(ruleForm,'disabled',count)
                    let code = count<10?`0${count}s後從新發送`: `${count}s後從新發送`
                    self.$globals.sendCode(self,ruleForm,opt.sendCode,code)
                    self.$globals.isChick(ruleForm,'isChick',count)
                    if(count<=0){
                        ruleForm.disabled = false
                        self.$globals.isChick(ruleForm,'disabled')
                        code = '發送驗證碼'
                        clearInterval(self.timer)
                        count =self.timeCount
                        self.$globals.sendCode(self,ruleForm,opt.sendCode,code)
                        self.$globals.isChick(ruleForm,'isChick')
                    }
                    count --
                },1000)

            },
            //發送驗證碼sendCode
            sendCode(opt){
                const phone = opt.phone
                //判斷手機號碼第1位是不是數字1開頭
                if(phone.slice(0,1)!=='1'){
                    this.$message({
                        showClose: true,
                        message: '請輸入正確的手機號碼',
                        type: 'error'
                    });
                    return
                }
                this.$confirm(`向${phone}發送短信驗證碼?`, '提示', {
                    confirmButtonText: '肯定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.$message({
                        type: 'success',
                        message: '發送短信驗證碼成功!'
                    });
                    const opt ={
                        dialog: 'dialog',
                        ruleForm: 'ruleForm',
                        sendCode:'sendCode'
                    }
                    this.sendCode60s(this,opt)
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '發送短信驗證碼失敗'
                    });
                });
            },
            //新的密碼
            determine(formName){
                console.log(formName)
                // this.$refs[formName].validate((valid) => {
                //     if (valid) {
                //         this.dialog.ruleForm.loading = true
                //         this.dialog.ruleForm.loadingText ='發送中...'
                //     } else {
                //         return false;
                //     }
                // });
            },
         
     }
 }
</script>
複製代碼
最終的截圖

gif的截圖

相關文章
相關標籤/搜索