防抖就是你使劲输入,直到几秒内不操作了,才执行,如果你一直点击他就不执行, 节流就是你使劲点击,它固定几秒执行一次
防抖
防抖: 即短时间内大量触发同一事件,只会执行一次函数
- 实现原理设置一个定时器,约定在xx毫秒后再触发事件处理,每次触发事件都会重新设置计时器,直到xx毫秒内无第二次操作
- 防抖常用于搜索框/滚动条的监听事件处理,如果不做防抖,每输入一个字/滚动屏幕,都会触发事件处理,造成性能浪费。
节流
防抖是延迟执行,而节流是间隔执行,函数节流即每隔一段时间就执行一次
- 实现原理为设置一个定时器,约定xx毫秒后执行事件,如果时间到了,那么执行函数并重置定时器
- 和防抖的区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器
在公共的js文件utils.js中添加防抖函数如下
export default {
debounce(func, delay = 300) { //防抖, 默认300毫秒
let timeout = null
return function () {
let context = this
let args = arguments
if (timeout) clearTimeout(timeout)
timeout = setTimeout(() => { // 一直输入timeout一直有值,就一直clearTimeout(timeout)
func.apply(context, args)
}, delay)
}
},
throttle(func, wait) { // 节流
let timeout = null
return function () {
let context = this
let args = arguments
if (!timeout) {
timeout = setTimeout(() => {
timeout = null
func.apply(context, args)
}, wait)
}
}
}
}
输入框搜索,输入几秒后执行
<input v-model="infos.name" @input='inputHandle' >
<el-button @click="clickHandle">{{num}}</el-button>
页面调用
<script>
import unit from '../js/utils'
export default {
name: 'index',
data() {
return {
num: 0,
infos: { // 表格参数
name: '',
},
};
},
methods: {
inputHandle: unit.debouncekkk(function () {
console.log('防抖成功');
let data = this.$post('Company/GetPage', this.infos); // 接口名称
data = data.data;
console.log('data', data);
}, 5000),
clickHandle: unit.throttle(function () {
this.num++
console.log(this.num);
}, 5000),
// inputHandle() {
// let a = unit.debouncekkk(function () { // this.debouncekkk(),把debouncekkk()方法写在这里面
// console.log(2222);
// }, 2000)
// a()
// },
},
};
</script>
func.apply(this, arguments);为何要这么写?
关键在第一个参数,为了确保上下文环境为当前的this,所以不能直接用fn。
请问为甚么你要确保 func 执行的上下文是this?在这个箭头函数里this又是指向的谁?
加上 apply 确保 在 inputHandle 函数里的 this 指向的是 input对象(不然就指向 window 了,不是我们想要的)。这里的箭头函数依旧是指向 input 对象。
不加apply时this是指向window的。因为 inputHandle 函数定义在全局中,所以调用时里面this指向window,所以才需要加上 apply,显示绑定 this 值(input对象)到 sayH 函数里面去