一、基本流程
【登錄界面】 --> 【點擊忘記密碼】 --> 【輸入個人郵箱和驗證碼】 --> 【系統發送郵箱驗證】 --> 【用戶在限定時間內登錄郵箱,查收驗證碼】 -->【完成身份驗證,進入重置密碼界面】-->【重置密碼,系統更新密碼】--> 【重置密碼完畢,點擊進入登錄界面】。
由於我們默認采用BUAA的郵箱進行身份驗證,故在身份驗證界面輸入學號,系統會向該學號相應的北航郵箱發送驗證碼信息。
二、主要界面
1、登陸界面
-
【忘記密碼】【還沒有賬號?點擊注冊】如何分別在一行的兩端顯示?
可以使用浮動float。
<div class="tips" style="float:left;"> <el-link type="white" @click="retrievePWD">忘記密碼</el-link> </div> <div class="tips" style="float:right;"> <el-link type="white" @click="regis">還沒有賬號?點擊注冊</el-link> </div>
-
點擊【忘記密碼】頁面跳轉
retrievePWD(){ this.$router.push({ path: '/retrievePassword' }) }
2、找回密碼界面
找回密碼界面我使用了vuetify的步驟條組件,分為三個步驟,框架如下:
<v-stepper v-model="e1">
<v-stepper-header>
<v-stepper-step :complete="e1 > 1" step="1">身份驗證</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step :complete="e1 > 2" step="2">密碼重置</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step step="3">重置完成</v-stepper-step>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<!-- 步驟一的內容-->
</v-stepper-content>
<v-stepper-content step="2">
<!-- 步驟二的內容-->
</v-stepper-content>
<v-stepper-content step="3">
<!-- 步驟三的內容-->
</v-stepper-content>
</v-stepper-items>
</v-stepper>
2.1 身份驗證界面
基本邏輯為:
【輸入學號】-->【點擊獲取郵箱驗證碼】(校驗學號格式是否正確;若正確,則后端判斷該學號是否已注冊。只有已注冊的學號,系統才會發送郵箱驗證碼,否則顯示錯誤信息)-->【前往郵箱,查收驗證碼並輸入】-->【點擊下一步】(向后端提交學號和驗證碼,后端判斷是否匹配,若匹配則身份驗證成功,進入重置密碼頁面,否則顯示錯誤信息)
-
element_ui表單驗證如何只讓它驗證其中一項?
// form為表單名字並ref="form"; prop 換成你想監聽的prop字段 this.$refs.form.validateField(prop, (errMsg) => { if (errMsg) { console.log('校驗失敗') }else{ //... } })
-
【獲取郵箱驗證碼】按鈕的實現
該按鈕具有倒計時功能,具體實現如下:
//msg綁定了按鈕顯示的內容 利用了vue的雙向綁定原理 <el-button plain :disabled="flag" @click="getAuthCode">{{ msg }}</el-button>
getAuthCode(){ //對輸入的學號格式進行校驗 this.$refs.form1.validateField('uid', (errMsg) => { if (errMsg) { console.log('學號校驗未通過') }else { var postData={ uid:this.form1.uid } //后端先判斷該學號是否存在,再給北航郵箱發送驗證碼 sendAuthCode(postData).then(res => { //獲取驗證碼按鈕倒計時功能的實現 const _this =this;//!!坑!setInterval中的this指向問題 this.flag = true; //!按鈕不可重復點擊 var time = 150;//定義時間變量 150s var timer = null;//定義定時器 timer = setInterval(function(){ if(time==0){ _this.msg="重新獲取驗證碼"; _this.flag=false; clearInterval(timer);//清除定時器 }else{ _this.msg=time+"秒后重新獲取"; time--; } },1000) }).catch(error => { console.log(error) }) } }) },
這里有幾個特別需要注意的地方(踩過的坑,大家小心!):
-
為了避免迅速點擊按鈕多次發送驗證碼的情況,需在點擊按鈕后,將按鈕設置為disabled屬性。
-
js代碼會從上到下執行,但是當遇到異步的情況,如axios請求時,並不會等拿到請求結果再做之后的操作,如果這時需要用到請求結果,則會出現錯誤,一般采用回調函數的方式解決。將需要請求數據的方法放在axios請求的回調函數中,待請求執行完成再做操作。
-
setInterval ()
中的this指向的是window中的對象,而非vue對象,這導致我一開始無法正確渲染msg的內容。故此處的解決辦法是,將當前對象的this存為另一個變量_this,在setInterval()
中進行指代。
-
2.2 重置密碼界面
在通過身份驗證之后,后端會返回pub_key
和key_id
等信息用於密碼的加密傳輸和身份匹配。這里不做介紹,詳見該項目的其他技術博客。
基本邏輯:
【輸入兩次密碼】-->【點擊下一步】(校驗密碼是否一致,若一致則將密碼加密傳給后端,否則顯示錯誤信息)-->【后端更新密碼】
-
校驗規則
var validatePass = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入密碼')); } else { if (this.form2.checkPass !== '') { this.$refs.form2.validateField('checkPass'); } callback(); } }; var validatePass2 = (rule, value, callback) => { if (value === '') { callback(new Error('請再次輸入密碼')); } else if (value !== this.form2.password) { callback(new Error('兩次輸入密碼不一致!')); } else { callback(); } }; rules2:{ password: [ { require: true, validator: validatePass, trigger: 'blur' } ], checkPass: [ { validator: validatePass2, trigger: 'blur' } ], },
-
前后端交互
nextStep2(formName){ console.log(formName); this.$refs[formName].validate((valid) => { if (valid) { var submitForm = { uid:this.uid, password: this.encryptPWD(this.form2.password), //傳回加密后的密碼 } console.log(submitForm) //與后端交互 resetPWD(submitForm).then(res => { this.e1=3;//進入下一步驟【重置完成】 }).catch(error => { console.log(error) }) } else { return false; } }) }
2.3 重置完成
- 【重新登陸】按鈕
<div class="text-center">
<v-btn color="primary" @click="login" >重新登錄</v-btn>
</div>
login() {
this.$router.push({ path: '/login' })
},