H5短信验证码功能,点击发送验证码调用后端接口,页面展示一分钟倒计时,倒计时结束重新显示发送验证码

image-20210806103748479

image-20210806111835724

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<li>
<span class="ipt-name accounts"></span>
<input
type="tel"
maxlength="11"
placeholder="请输入手机号"
v-model="phone"
/>
</li>
<li>
<span class="ipt-name note"></span>
<input
type="text"
maxlength="11"
placeholder="请输入验证码"
v-model="smsCode"
/>
<span class="verify-text js_verify" @click="sendMsg">{{
textMsg
}}</span>
</li>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
export default {
data() {
return {
smsCode: "", //短信验证码
phone: "", //手机号
textMsg: "发送验证码",
timeNum: 60, //计时器
clock: "",
};
},
methods: {
//发送验证码
sendMsg() {
if (this.timeNum == 60) {
var reg =
/^(((13[0-9]{1})|(15[0-9]{1})|(16[0-9]{1})|(17[3-8]{1})|(18[0-9]{1})|(19[0-9]{1})|(14[5-7]{1}))+\d{8})$/;
if (this.phone == "") {
this.$toast.showToast("请输入手机号");
return;
} else if (!reg.test(this.phone)) {
this.$toast.showToast("请输入正确格式手机号");
return;
}
this.textMsg = this.timeNum + "s后可重获";
this.clock = setInterval(this.doLoop, 1000); //一秒执行一次
console.log(this.clock);
sendMsg({
phone: this.Phone,
type: 1,
})
.then((res) => {
if(res.resCode !== "000000"){
this.$toast.showToast(res.resMsg);
clearInterval(this.clock); //清除js定时器
this.textMsg = "发送验证码";
this.timeNum = 60; //重置时间
}
}
})
.catch((err) => {
this.$toast.showToast(err);
});
} else {
return;
}
},
doLoop() {
this.timeNum--;
if (this.timeNum > 0) {
this.textMsg = this.timeNum + "s后可重获";
} else {
clearInterval(this.clock); //清除js定时器
this.textMsg = "发送验证码";
this.timeNum = 60; //重置时间
}
},
}
}

这里用到了节流的方法处理。

函数防抖(debounce):触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。

函数节流(throttle):高频事件触发,但在n秒内只会执行一次,节流会稀释函数的执行频率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//防抖debounce代码:
function debounce(fn,delay) {
var timeout = null; // 创建一个标记用来存放定时器的返回值
return function (e) {
// 每当用户输入的时候把前一个 setTimeout clear 掉
clearTimeout(timeout);
// 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发,就不会执行 fn 函数
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
};
}
// 处理函数
function handle() {
console.log('防抖:', Math.random());
}

//滚动事件
window.addEventListener('scroll', debounce(handle,500));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//节流throttle代码:
function throttle(fn,delay) {
let canRun = true; // 通过闭包保存一个标记
return function () {
// 在函数开头判断标记是否为true,不为true则return
if (!canRun) return;
// 立即设置为false
canRun = false;
// 将外部传入的函数的执行放在setTimeout中
setTimeout(() => {
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
// 当定时器没有执行的时候标记永远是false,在开头被return掉
fn.apply(this, arguments);
canRun = true;
}, delay);
};
}

function sayHi(e) {
console.log('节流:', e.target.innerWidth, e.target.innerHeight);
}
window.addEventListener('resize', throttle(sayHi,500));