瑞吉外卖移动端开发登录发送短信验证码
问题描述
瑞吉外卖移动端开发登录发送短信验证码时,获取验证码可以点击多次,对于用户以及开发者都不友好。如果用户点击多次,用户会收到好几条,开发者将会花费更多短信额度!这对于一个大学生来说 就是晴天霹雳、雪上加霜 (虽然阿里云注册送了一百条)。而且,阿里云短信服务测试的时候,同一个号码一个小时之内只能发送5条,点击获取获取不到,我还以为是我的代码出现了问题,用阿里云短信服务测试之后,显示:触发小时级流控permits:5。
原因分析:
问题分析:
<span @click='getCode'>获取验证码</span>
因为是span标签,所以禁用标签 disabled 也失效了,所以可以点击多次获取验证码,导致发送多次短信验证码。
解决方案:
我们需要将这个span标签改成button标签,并且在第一次点击发送后,将按钮改为禁用并且加上定时器,限制60s发送一次验证码。
第1步:将 span 标签
<span @click='getCode'>获取验证码</span>
改为 el-button标签
<el-button class="code-btn" :disabled="countdown > 0" @click='getCode'>{{ countdown > 0 ? countdown + '秒' : '获取验证码' }}</el-button>
:disabled="countdown > 0" 设置按钮的 disabled 属性,如果 countdown 变量大于 0,则将其设置为 true ,防止在倒计时进行时点击。
{{ countdown > 0 ? countdown + '秒' : '获取验证码' }} 显示 剩余时间 或 "获取验证码",具体取决于 countdown 的值。如果 countdown 大于 0,则将显示剩余的时间。否则,将显示 "获取验证码"。
第2步:将code-btn的css加入到 login.css 也就是 19行的
<link rel="stylesheet" href="./../styles/login.css" />
.code-btn {
padding: 0;
}
第3步:在JavaScript中加入定时器默认值、定时器和获取验证码的返回信息弹窗提醒。
data() {
return {
countdown: 0,
timer: null,
form: {
phone: '',
code: ''
},
msgFlag: false,
loading: false
}
},
async getCode() {
this.form.code = ''
const regex = /^(13[0-9]{9})|(15[0-9]{9})|(17[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})$/;
if (regex.test(this.form.phone)) {
this.msgFlag = false;
// this.form.code = (Math.random()*1000000).toFixed(0)
const res = await sendMsgApi({phone: this.form.phone})
if (res.code === 1) {
this.countdown = 59;
this.timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--;
} else {
clearInterval(this.timer);
this.timer = null;
}
}, 1000);
this.$notify({type: 'success', message: '手机验证码短信发送成功'});
} else {
this.$notify({type: 'warning', message: res.msg});
}
} else {
this.msgFlag = true
}
}
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
watch: {
countdown: {
handler(newVal) {
this.countdown = newVal
}
}
}
beforeDestroy(),通常用于在组件销毁之前清理工作。
如果计时器this.timer存在,则会通过clearInterval(this.timer)清除计时器,然后将this.timer设置为null。
创建了一个名为“countdown”的观察器,用于监听countdown属性的变化。
当countdown属性的值发生变化时,观察器会将新的值分配给this.countdown。
完整JavaScript代码如下:
new Vue({
el: "#login",
data() {
return {
countdown: 0,
timer: null,
form: {
phone: '',
code: ''
},
msgFlag: false,
loading: false
}
},
computed: {},
created() {
},
mounted() {
},
methods: {
async getCode() {
this.form.code = ''
const regex = /^(13[0-9]{9})|(15[0-9]{9})|(17[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})$/;
if (regex.test(this.form.phone)) {
this.msgFlag = false;
// this.form.code = (Math.random()*1000000).toFixed(0)
const res = await sendMsgApi({phone: this.form.phone})
if (res.code === 1) {
this.countdown = 59;
this.timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--;
} else {
clearInterval(this.timer);
this.timer = null;
}
}, 1000);
this.$notify({type: 'success', message: '手机验证码短信发送成功'});
} else {
this.$notify({type: 'warning', message: res.msg});
}
} else {
this.msgFlag = true
}
},
async btnLogin() {
if (this.form.phone && this.form.code) {
this.loading = true
const res = await loginApi({phone: this.form.phone,code: this.form.code})
this.loading = false
if (res.code === 1) {
sessionStorage.setItem("userPhone", this.form.phone)
window.requestAnimationFrame(() => {
window.location.href = '/front/index.html'
})
} else {
this.$notify({type: 'warning', message: res.msg});
}
} else {
this.$notify({type: 'warning', message: '请输入手机号码'});
}
}
},
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
watch: {
countdown: {
handler(newVal) {
this.countdown = newVal
}
}
}
})
优化效果如图:
文章到此结束!仅作学习参考!谢谢!