防抖就是指在连续的触发过程中,只执行一次响应,这个【连续的触发过程】没有时间限制,如果一直触发,那么消抖就没结束;
节流是指在一个时间段内,只执行一次响应,和防抖不同的是,如果在【连续的触发过程】中,是可能不止一次响应的,取决于截流时间。
防抖和截流还可以细分为立即执行和非立即执行两种情况,没有特殊情况,两种选其一即可。
选用一个现成的项目vue-template-admin,页面添加一个按钮,添加一个点击事件来模拟点击操作。
防抖
非立即执行版:编辑/src/utils/debounce.js
export const debounce = (fun, delay) => {
let timeout
return (params) => {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(() => {
fun.call(this, params)
}, delay)
}
}
在连续触发的过程中,如果已经给timeout赋值了,就清空,再重新赋值timeout,这样就能一直更新timeout,直到连续触发的过程结束,最后延时函数结束后就执行里面的fun函数
编辑dashboard/index.vue
<template>
<el-button @click="handleClick(222)">Click me</el-button>
</template
import{ debounce } from '@/utils/debounce'
export default {
data() {
return {
myFun: null
}
}
methods: {
handleClick(value){
console.log('click')
if(!this.myFun){
this.myFun = debounce(this.getData, 500)
}
this.myFun()
},
getData(args) {
console.log(`args=${args}`)
}
}
}
连续点击,只响应最后一次事件,并且参数也传进去了
立即执行版:
export const debounce2 = (fun, delay) => {
let timeout
return (params) => {
if (!timeout) fun.call(this, params)
if (timeout) clearTimeout(timeout)
timeout = setTimeout(() => {
timeout = null
}, delay)
}
}
在连续触发的过程中,如果timeout为空,就先执行一次fun,然后给timeout赋值,在接下来的过程中不断的给timeout重新赋值,直到连续触发的过程结束,然后延时函数结束,再清空timeout,等待下次触发。
查看结果:
节流
立即执行版:
export const throttle = (fun, delay) => {
let flag = true
return (params) => {
if (flag) {
fun.call(this, params)
flag = false
setTimeout(() => {
flag = true
}, delay)
}
}
}
维护一个flag标志,在连续的触发过程中,flag为true的时候就执行fun方法,执行完就清空flag等待倒计时结束后再把flag置为true,不论这个过程有多长,只要在设定的时间间隔内都会调用fun
查看结果:
// 也可以直接用timeout做标志位
export const throttle2 = (fun, delay) => {
let timeout
return (params) => {
if (!timeout) {
fun.call(this, params)
timeout = setTimeout(() => {
timeout = null
}, delay)
}
}
}
非立即执行:
export const throttle3 = (fun, delay) => {
let timeout
return (params) => {
if (!timeout) {
timeout = setTimeout(() => {
fun.call(this, params)
timeout = null
}, delay)
}
}
}
把fun放到timeout回调里,就是非立即执行的了,他会等倒计时函数结束才执行。
查看结果: