vue中使用闭包(防抖和节流)失效问题

 更新时间:2023年04月30日 08:57:54   作者:凡小多  
本文主要介绍了vue中使用闭包(防抖和节流)失效问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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 闭包失效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue使用keep-alive保持滚动条位置的实现方法

    vue使用keep-alive保持滚动条位置的实现方法

    这篇文章主要介绍了vue使用keep-alive保持滚动条位置的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • vue3中如何使用live2D

    vue3中如何使用live2D

    本文介绍了如何在Vue3项目中整合Live2D技术,从Live2D的基本介绍到在Vue3中的具体实现方法,Live2D技术允许开发者将二维图像转化为可动画的三维模型,主要应用于游戏、虚拟角色等领域,文章详细说明了在vue3项目中使用Live2D的步骤,感兴趣的朋友一起看看吧
    2024-10-10
  • vue中keep-alive、activated的探讨和使用详解

    vue中keep-alive、activated的探讨和使用详解

    这篇文章主要介绍了vue中keep-alive、activated的探讨和使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • Vue.js做select下拉列表的实例(ul-li标签仿select标签)

    Vue.js做select下拉列表的实例(ul-li标签仿select标签)

    下面小编就为大家分享一篇Vue.js做select下拉列表的实例(ul-li标签仿select标签),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • Vue.directive 实现元素scroll逻辑复用

    Vue.directive 实现元素scroll逻辑复用

    这篇文章主要介绍了Vue.directive 实现元素scroll逻辑复用功能,文中给大家提到元素实现滚动的条件有两个,具体内容详情大家参考下本文
    2019-11-11
  • Vue踩坑之Vue Watch方法不能监听到数组或对象值的改变详解

    Vue踩坑之Vue Watch方法不能监听到数组或对象值的改变详解

    Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性,下面这篇文章主要给大家介绍了关于Vue踩坑之Vue Watch方法不能监听到数组或对象值的改变的相关资料,需要的朋友可以参考下
    2022-04-04
  • vue.js实现单选框、复选框和下拉框示例

    vue.js实现单选框、复选框和下拉框示例

    本篇文章主要介绍了vue.js实现单选框、复选框和下拉框示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • vuecli+AXdownload下载组件封装 +css3下载悬浮球动画效果

    vuecli+AXdownload下载组件封装 +css3下载悬浮球动画效果

    当触发下载功能的时候,会触发一个下载动画,下载悬浮球会自动弹出,并且闪烁提示有新的下载任务直到下载任务完场提示,接下来通过本文介绍vuecli+AXdownload下载组件封装 +css3下载悬浮球动画效果,需要的朋友可以参考下
    2024-05-05
  • vue2.0数据双向绑定与表单bootstrap+vue组件

    vue2.0数据双向绑定与表单bootstrap+vue组件

    这篇文章主要介绍了vue2.0数据双向绑定与表单bootstrap+vue组件,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-02-02
  • VUE如何利用vue-print-nb实现打印功能详解

    VUE如何利用vue-print-nb实现打印功能详解

    这篇文章主要给大家介绍了关于VUE如何利用vue-print-nb实现打印功能的相关资料,文中还给大家介绍了vue-print-nb使用中的常见问题,如空白页,需要的朋友可以参考下
    2022-04-04

最新评论