防抖
当我们使用搜索框输入内容时,会发现每一个动作会被输出一次。如果此时的搜索框有调接口,那么没输入一次就会调用一次接口,大大浪费网络资源。
我们要做的就是只要最后的那个输入内容,也就是一段时间只触发最后的那个。需要加个定时器,在一段时间内只触发一次-
<input type="text" :value="value" @input="oninput" />
export default {
data() {
return {
value: '',
timer: null,
}
},
methods: {
oninput(e) {
this.timer && clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.value = e.data
console.log(e.data)
}, 3000)
},
},
}
使用场景
- 按钮提交场景:防止多次点击提交按钮,只执行最后提交的一次
- 服务端验证场景:表单验证需要服务端配合,只执行一段连续的输入事件的最后一次,还有搜索联想词功能类似。
手写防抖
function debounce(fn, wait = 500, immediate = false) {
let timer = null;
// 返回一个函数,这个函数会在一个时间区间结束后的 wait 毫秒执行 fn 函数
return function (...args) {
// 是否立即执行
if (immediate) {
fn.apply(this, args);
}
// 函数被调用,清除定时器
timer && clearTimout(timer);
// 当返回的函数被最后一个调用后(也就是用户停止了某个连续的操作)
// 再过 wait 毫秒就执行 func
// 这里直接使用箭头函数就不用保存执行上下文的引用了
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
节流
鼠标移动一次,就会输出一次123,为了少输几次123,控制执行的次数。
使用场景
- 动画场景:避免短时间内多次触发动画引起性能问题
- 拖拽场景:固定时间内只执行一次,防止超高频次触发位置变动(mousemove)
- 缩放场景:监控浏览器窗口大小(resize)
- 滚轮场景:鼠标滚轮事件(wheel)
- Canvas 画笔功能
手写节流
function throttle(fn, wait = 500) {
// 利用闭包保存定时器和上次执行时间
// 上次执行时间
let timer = null,
last;
return function (...args) {
const now = new Date();
if (last && now < last + timeout) {
clearTimeout(timer);
timer = setTimeout(() => {
last = now;
fn.apply(this, args);
}, timeout);
} else {
last = now;
fn.apply(this, args);
}
};
}