vue中使用闭包(防抖和节流)失效问题
短信预约 -IT技能 免费直播动态提醒
1. 出现问题
防抖/节流使用无效,(例如防抖,按钮点击多次依旧执行多次)
----> 查看是闭包无效,定义的局部变量依旧为初值
----> 没有相应清除定时器
<el-button @click="btn1">按 钮1</el-button>
<el-button @click="debounce(btn2)">按 钮2</el-button>
</template>
<script setup lang="ts">
// 以下方法调用不生效
const btn1 = () => {
debounce(() => {
console.log('点击了')
}, 1000)()
}
const btn2 = () => {
console.log('点击了');
}
</script>
2. 问题原因
直接调用了防抖函数
原因:这个和vue的事件绑定原理有关。如果直接在函数体内部使用的话,结果就是,一个匿名的立即执行函数来进行执行。由于每次触发点击事件都会返回一个新的匿名函数, 就会生成一个新的函数执行期上下文(称之为执行栈),所以就会防抖/节流就会失效
3. 解决办法
<template>
<el-button @click="btn">按 钮1</el-button>
</template>
<script setup lang="ts">
const btn = debounce(function() {
console.log('点击了');
},500)
</script>
4. 防抖节流函数
type DebouncedFn<T extends (...args: any[]) => any> = (this: ThisParameterType<T>, ...args: Parameters<T>) => void;
type ThrottledFn<T extends (...args: any[]) => any> = (this: ThisParameterType<T>, ...args: Parameters<T>) => void;
function debounce<T extends (...args: any[]) => any>(fn: T, delay: number, immediate = false): DebouncedFn<T> {
let timer: number | null = null;
return function(this: ThisParameterType<T>, ...args: Parameters<T>) {
// if (timer !== null) clearTimeout(timer);
timer && clearTimeout(timer)
if (immediate) {
const callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, delay);
callNow && fn.apply(this, args);
} else {
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
}
};
}
function throttle<T extends (...args: any[]) => any>(fn: T, delay: number, immediate = false): ThrottledFn<T> {
let lastCall = 0;
return function(this: ThisParameterType<T>, ...args: Parameters<T>) {
const now = new Date().getTime();
// immediate 不为 true 时, 不立即执行
lastCall === 0 && !immediate && (lastCall = now)
const diff = now - lastCall;
if (diff >= delay) {
lastCall = now;
fn.apply(this, args);
}
};
}
export {
debounce,
throttle
}
到此这篇关于vue中使用闭包(防抖和节流)失效问题的文章就介绍到这了,更多相关vue 闭包失效内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341