最近在写项目时,进行性能优化时用到了防抖节流。然后直接就开始面向csdn开始搜索,什么使用方法啊,在项目中如何使用啊。本来认为会一帆风顺然后就是遇到了坑,跟预想的所不太一样。然后就手写了一下果然茅塞顿开啊。下面就给大家总结一下子在项目中如何使用跟自己的一点理解。skr~~~skr~~~skr~~~
先来一波知识点总结
防抖(debounce)
大家都玩过王者农药吧,其实就是回城,反正我就是这么理解的。防抖就是当事件触发时,设定一个周期延迟动作,当你再次触发时重新设定周期。直到周期结束后执行事件。后期的话还加了一个点击时是否触发一次事件。
节流(throttling)
节流在王者农药的话,可以理解为技能CD,技能冷确没好怎么能释放技能的。节流的话就是在一定周期内只触发一次事件,结束周期后在重新执行。后期的话还有什么首节流,尾节流。就是第一次是否触发事件,最后一下是否触发函数。
1、使用防抖
1,使用lodash里面的防抖(常用)
注意:debounce里面是可以传3个参数的,想要里了解的话也可以去lodash官方查看。
<template>
<div class="main">
<el-input v-model="inputVal" placeholder="请输入内容" @input="inputChange"></el-input>
</div>
</template>
<script>
//引入lodash
import lodash from "lodash";
export default {
name: "HelloWorld",
data() {
return {
inputVal: "",
};
},
methods: {
inputChange: lodash.debounce(function (val) {
console.log("---输入框内容(lodash)---", val); //业务逻辑
console.log("---发送请求---"); //业务逻辑
}, 1000),
},
};
</script>
<style scoped>
</style>
2.手写的防抖函数进行封装
export function debounce (fn, delay,immediate=false) { //最后一个参数默认为false表示第一次点击的事件不执行
let time = null
let isInvoke = false
return function(...args){
if(time){
clearTimeout(time)
}
if (immediate && !isInvoke) { //如果需要第一次调用的话 二者皆为真 直接调用函数 反之直接跳过
fn.apply(this, args)
isInvoke = true
}else{
time = setTimeout(()=>{
fn.apply(this, args)
isInvoke = false
},delay)
}
}
}
2、使用节流
1,使用lodash里面的节流(常用)
注意:throttle里面是可以传3个参数的,想要里了解的话也可以去lodash官方查看。
<template>
<div class="main">
<el-button type="plain" @click="search">搜索</el-button>
</div>
</template>
<script>
import lodash from "lodash";
export default {
name: "HelloWorld",
methods: {
search: lodash.throttle(
function () {
console.log("---发送请求---"); //业务逻辑
},
3000,
{ trailing: false } //一定要传入这个参数否则的话在3秒内多次点击会调用2次
),
},
};
</script>
<style scoped>
</style>
2.手写的防抖函数进行封装
export function throttle(fn, interval, option = { leading: true, trailing: false }) {
const { leading, trailing } = option //点击时第一次跟最后一次是否调用的参数
let lastTime = 0 //最后点击的时间
let timer = null //定时器先赋值一下
return function (...args) {
const nowTime = new Date().getTime() //获取当前点击的时间
if (!lastTime && !leading) {
lastTime = nowTime
}
const remainTime = interval - (nowTime - lastTime) //还需要多长时间去触发函数
if (remainTime <= 0) {
if (timer) { //如果有定时器清除一下
clearTimeout(timer)
timer = null
}
fn.apply(this, args) //调用函数 并且改变this的指向
lastTime = nowTime //把当前点击的时间赋值给最后一次点击的时间
}
if (trailing && !timer) {
timer = setTimeout(() => {
timer = null
lastTime = !leading ? 0 : new Date().getTime()
fn.apply(this, args)
}, remainTime);
}
};
}
总结:根据不同的业务选择使用。使用lodash里面的节流时,是需要传入第3个参数的,否则的话就会调用2次。这是我困惑了老长时间的问题,还是手写了一下才知道的事情。建议大家手写一下这样理解的会更为透彻。