什么是函数的防抖?什么场景下使用防抖函数?
高频率触发一个事件,比如点击事件,点击以后新建一条消息或是一个任务,每次点击都会调用后端接口,那么就会造成一些没必要的请求,和开销,那么用户在不断点击的过程中让前面的点击都不会去发请求,只有最后一次才去发请求,这样,就能防止用户恶意的去做一些操作,造成不必要的网络浪费;
在Vue中如何使用防抖呢?
首先准备一个防抖的函数,在utils文件夹下新建一个tool.js文件,所有的工具函数都放在里面
export const debounce = function (func, delay = 300) {
let context = this as any;//在ts中需要这样写
let args = arguments;
return function () {
if (context.timeout) {
clearTimeout(context.timeout);
}
context.timeout = setTimeout(() => {
func.apply(context, args);
}, delay);
};
};
export const throttle = function(func,delay = 300){
let context = this as any;
let args = arguments;
return function(){
if (context.timeout) {
return
}
context.timeout = setTimeout(() => {
func.apply(context, args);
context.timeout = null;
},delay)
}
}
debounce函数接收两个参数,第一个参数就是要执行的回调函数,第二个参数是一个时间长度的参数,比如1s,2s,默认300ms,这个函数的意思就是,当第一次点击的时候判断vue实例–context上面没有定时器id – timeout,那么就会开启一个定时器放在vue实例上,同时在延迟delay这个时间后再执行回调func,当用户在这个时间内又点击了第二次,那么就会把上一次的定时器清除掉,把第二次的定时器赋值给vue实例身上,时间又会重新计算,只要是你在这个时间段内去触发事件,那么前面的事件回调永远都不会触发,只会触发最后一次的回调;
然后在组件中使用
首先引入防抖函数
import { debounce } from "@/utils/tools";
addTask() {
debounce.bind(this)(() => {
this.creatTask();
}, 400)();
}
这里点击的时候就会去调用debounce函数,因为debounce中需要vue的实例,所以在这里使用了bing(this),bind的特性是不会调用函数,所以后面再调用并且传入回调函数和时间,本以为这样就ok了,在实际开发中发现并非如此,因为我们每次点击,每次调用debounce 返回的是一个匿名函数,所以在这里需要再次自动调用一下;