前言
最近博主的前端项目里有一个需求是点击获取验证码按钮后,进入倒计时,重新进入该页面后,不重置。博主在了解需求后,实操了一波,特地记录实操的代码供代码参考使用
前端代码
<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秒。