一、什么是节流?
节流就是指动作绑定事件后,动作触发事件,在这段时间内,如果动作又发生,则无视该动作,直到事件执行完后,才能重新触发。
二、应用场景:
比如提交按钮,登录按钮等一些需要完成资源请求(如发起ajax)的操作,它可以一定程度避免用户短时间内多次请求资源导致的错误。
三、如何实现:
首先我们先准备一下data中的数据
data() {
return {
count: 0,
isWork: false, //记录定时器是否运行,默认false
isView: null, //记录disabled绑定的属性,
waitTimg:3000,//设置等待时间
};
},
然后我们再模板中写好按钮,用count记录我们成功点击了几次,用isWork记录当前定时器是否正在工作
<button @click="btn($event, waitTimg)" :disabled="isView">节流按钮</button>
<p>请求了{{ count }}次,定时器当前的状态是{{ isWork }}</p>
然后是函数部分,我们把异步的操作(或者说要实现的业务)和节流分开来写,@click直接绑定btn(),addCount代表要实现的业务,btn是节流判断,这里我们传入两个参数,第一个是接收鼠标点击事件的,可以省略,第二个我们传入节流的时间间隔,笔者这边设置的是3000也就是3s。
逻辑是:当第一次点击的时候,初始定时器是false也就是没有定时器在运行,所以我们的判断条件成立,执行业务代码(对应图中调用addCount函数),然后此时将定时器状态设置为true,接着开启一个定时器,执行我们设定的时间,时间到之后把定时器状态设置为false。当第二次点击的时候,如果定时器状态是ture直接return,不发起业务代码的调用。
methods: {
//执行异步操作,这里可以发起ajax请求,笔者只是用定时器模拟异步操作
addCount() {
setTimeout(() => {
this.count += 1;
}, 500);
},
//绑定的事件
btn(e, wait) {
console.log(e);
if (!this.isWork) {
this.addCount();
this.isWork = true;
let timeOut = setTimeout(() => {
this.isWork = false;
}, wait);
return;
} else {
return;
}
},
},
最后我们再加一层保险,让定时器工作的时候按钮不可点击,进一步防止用户在设定时间内多次操作。
通过监听isWork定时器状态,为按钮的disabled动态绑定属性。
这边要注意设置immediate: true,保证初始化的时候就监听一次,并且由于初始化监听的时候只有旧值,新值是undefined,所以要给if多一个类型判断。
watch: {
//监听定时器状态,动态修改disabled属性
isWork: {
immediate: true, //设置初始化监听一次
handler(oldval, newval) {
if (typeof newval === "undefined" || newval === true) {
this.isView = null;
} else {
this.isView = "disabled";
}
},
},
},
四、效果:
初始:
点击一次:按钮置灰,无法点击,并且定时器正在计时
3s之后,定时器停止工作,按钮恢复可点击状态。
五、总结
以上就是节流操作的简单实现,在真实开发中我们可能会对这样的操作进行封装,让代码的复用性更强,如果有讲的不对的地方欢迎指正哈。