前言
最近博主的前端項目裏有一個需求是點擊獲取驗證碼按鈕後,進入倒計時,重新進入該頁面後,不重置。博主在瞭解需求後,實操了一波,特地記錄實操的代碼供代碼參考使用
前端代碼
<template>
<el-dialog :visible.sync="dialog" :close-on-click-modal="false" :before-close="cancel" :title="title" append-to-body @open="getCode"
width="475px" @close="cancel" v-cloak>
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="88px">
<el-form-item label="新郵箱" prop="email">
<el-input v-model="form.email" auto-complete="on" style="width: 200px;" clearable />
<el-button :loading="codeLoading" type="primary" :disabled="isDisabled" size="small" @click="sendCode">
{{ buttonName }}
</el-button>
</el-form-item>
<el-form-item label="驗證碼" prop="code">
<el-input v-model="form.code" style="width: 320px;" clearable />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancel">取消</el-button>
<el-button :loading="loading" type="primary" @click="doSubmit">確認</el-button>
</div>
</el-dialog>
</template>
<script>
import {
resetEmail,
sendEmailCode
} from '@/apis/email'
import {
validedEmail
} from '@/utils/validate'
import {
mapGetters
} from 'vuex'
import {
setItemByKey,
getItemByKey,
removeItemByKey
} from '@/utils/sessionStorageUtils'
export default {
computed: {
...mapGetters([
'userInfo'
])
},
props: {
email: {
type: String,
required: true
}
},
data() {
const validMail = (rule, value, callback) => {
if (value === '' || value === null) {
callback(new Error('新郵箱不能爲空'))
} else if (value === this.email) {
callback(new Error('新郵箱不能與舊郵箱相同'))
} else if (validedEmail(value)) {
callback()
} else {
callback(new Error('郵箱格式錯誤'))
}
}
return {
loading: false,
dialog: false,
title: '修改郵箱',
form: {
email: '',
code: ''
},
codeLoading: false,
buttonName: '獲取驗證碼',
isDisabled: false,
time: 60,
timer: null,
rules: {
email: [{
required: true,
validator: validMail,
trigger: 'blur'
}],
code: [{
required: true,
message: '驗證碼不能爲空',
trigger: 'blur'
}]
}
}
},
methods: {
cancel() {
this.resetForm()
},
// 獲取驗證碼
getCode() {
// 獲取之前點擊獲取郵箱驗證碼時輸入的郵箱
if (getItemByKey('emain-code-fill-person')) {
this.form.email = getItemByKey('emain-code-fill-person')
}
if (getItemByKey('emain-code-startTime')) {
// 獲取 點擊獲取驗證時保存的時間毫秒值
let startDate = getItemByKey('emain-code-startTime')
// 計算現在時間與startDate的時間差
let timeDifference = parseInt((new Date().getTime() - startDate) / 1000)
const _this = this;
if(timeDifference <= 60) {
this.time = this.time - timeDifference;
_this.buttonName = this.time + '秒後重新發送'
this.isDisabled = true
this.countdown(_this);
}
}
},
// 發送驗證碼
sendCode() {
if (this.form.email && this.form.email !== this.email) {
this.codeLoading = true
this.buttonName = '驗證碼發送中'
setItemByKey('emain-code-fill-person', this.form.email)
setItemByKey('emain-code-startTime', new Date().getTime())
const _this = this
sendEmailCode(this.form.email).then(res => {
this.msgSuccess(res.message)
this.codeLoading = false
this.isDisabled = true
this.buttonName = this.time + '秒後重新發送'
this.countdown(_this);
}).catch(err => {
this.resetForm()
this.codeLoading = false
console.log(err.response.data.message)
})
} else {
this.warningNotify("請輸入郵箱")
}
},
// 開始倒計時
countdown(_this) {
this.timer = setInterval(() => {
--_this.time
_this.buttonName = _this.time + '秒後重新發送'
if (_this.time < 0) {
_this.buttonName = '重新發送'
_this.time = 60
_this.isDisabled = false
clearInterval(_this.timer)
removeItemByKey('emain-code-startTime')
}
}, 1000)
},
doSubmit() {
this.$refs['form'].validate((valid) => {
if (valid) {
this.loading = true
this.form.username = this.userInfo.username;
resetEmail(this.form).then(res => {
this.loading = false
this.resetForm()
this.successNotify("郵箱修改成功")
}).catch(err => {
this.loading = false
this.errorNotify(err.response.data.message)
})
} else {
return false
}
})
},
resetForm() {
this.dialog = false
this.$refs['form'].resetFields()
window.clearInterval(this.timer)
this.time = 60
this.buttonName = '獲取驗證碼'
this.isDisabled = false
this.form = {
email: '',
code: ''
}
}
}
}
</script>
<style scoped>
/deep/ .el-dialog__header {
padding: 20px;
}
/deep/ .el-dialog__body {
padding: 30px 20px 15px 20px;
border-top: 1px solid #e8e8e8;
border-bottom: 1px solid #e8e8e8;
}
/deep/ .el-dialog__footer {
padding: 20px;
}
</style>
本代碼是將獲取郵箱驗證碼抽離成組件的形式。大夥只要關注getCode函數、sendCode函數和countdown函數代碼邏輯即可。
其核心實現是在點擊發送驗證碼的時候,將當前時間毫秒值保存到sessionStorage中,然後進入倒計時階段,退出當前頁面,重新進入到該頁面時,利用el-dialog組件的open方法回調,調取getCode方法,從sessionStorage中獲取點擊獲取驗證時保存的時間毫秒值,然後與當前時間毫秒值進行比較,如果時間差小於等於60,那麼都還在倒計時的過程中,那麼此時發送驗證碼的按鈕不允許點擊,並且內容爲“xxx秒後重新發送”,直到時間差大於60秒。