vue 防抖函数、节流函数,工具类封装及遇到的问题

7 篇文章 0 订阅

防抖函数(可用于防止重复提交)

当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次, 如果设定时间到来之前,又触发了事件,就重新开始延时。也就是说当一个用户一直触发这个函数,且每次触发函数的间隔小于既定时间,那么防抖的情况下只会执行一次。

/**
* 防抖函数(可用于防止重复提交)
* 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,
* 如果设定时间到来之前,又触发了事件,就重新开始延时。也就是说当一个用户一直触发这个函数,
* 且每次触发函数的间隔小于既定时间,那么防抖的情况下只会执行一次。
*
* @param func 执行函数
* @param wait 间隔时间
* @param immediate 立即执行
*/
function debounce(fn, wait, immediate) {
   let timer;
   return function() {
       if (timer) clearTimeout(timer);
       if (immediate) {
           // 如果已经执行过,不再执行
           var callNow = !timer;
           timer = setTimeout(() => {
               timer = null;
           }, wait)
           if (callNow) {
               fn.apply(this, arguments)
           }
       } else {
           timer = setTimeout(() => {
               fn.apply(this, arguments)
           }, wait);
       }
   }
}

节流函数

当持续触发事件时,保证在一定时间内只调用一次事件处理函数,意思就是说,假设一个用户一直触发这个函数,且每次触发小于既定值,函数节流会每隔这个时间调用一次
用一句话总结防抖和节流的区别:防抖是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行
实现函数节流我们主要有两种方法:时间戳和定时器

/**
 * 节流函数
 * 当持续触发事件时,保证在一定时间内只调用一次事件处理函数,意思就是说,假设一个用户一直触发这个函数,且每次触发
 * 小于既定值,函数节流会每隔这个时间调用一次
 * 用一句话总结防抖和节流的区别:防抖是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行
 * 实现函数节流我们主要有两种方法:时间戳和定时器
 *
 * @param func 执行函数
 * @param wait 间隔时间
 * @param options 立即执行
 * options中  leading:false 表示禁用第一次执行 trailing: false 表示禁用停止触发的回调
 */
function throttle(fn, wait, options = {}) {
    let timer;
    let previous = 0;
    let throttled = function() {
        let now = +new Date();
        // remaining 不触发下一次函数的剩余时间
        if (!previous && options.leading === false) previous = now;
        let remaining = wait - (now - previous);
        if (remaining < 0) {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            previous = now;
            fn.apply(this, arguments)
        } else if (!timer && options.trailing !== false) {
            timer = setTimeout(() => {
                previous = options.leading === false ? 0 : new Date().getTime();
                timer = null;
                fn.apply(this, arguments);
            }, remaining);
        }
    }
    return throttled;
}

vue中调用防抖函数不生效的解决方法

import {debounce} from "../../util.js"
 add(e){
            debounce(function(){
                console.log("点击")
            },500)
        }
    }

最开始向上面这样写,会发现debounce函数执行了,但是其返回的一个延时函数并没有执行。仔细检查发现,没有调用执行其返回的一个函数。所以应该将调用处改为如下;

 add(e){
            // console.log("点击")
            // delay(()=>{
            //     console.log("点击")
            // },500)
            debounce(function(){
                console.log("点击")
            },500)()//加括号表示调用其返回的那个函数
        }
    }

现在的问题

首先 如果以以上的方式 来存timer等外层变量 有两种情况使用保留 且不同组件不相互影响

1.组件中引入工具对象,可以同样选择在data中增加一个debounceFn:null句柄来保存这个闭包,然后在组件初始化阶段给设置好 如图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0QCYUjJs-1622432123960)(http://doc.tianbp.com/server/index.php?s=/api/attachment/visitFile/sign/fd653d47526726a5e5e54bc76ca76666)]

2.存到methods会相对好点(记得拆闭包)

methods: { handleInputChange:utl.debounce(function(){
      console.log(this.inputText);
    },1500)
  },
  watch: {
    inputText(newVal) {
      if (newVal !== "") {
        // 经过节流
        this.handleInputChange();
      }
    }
  },
  beforeDestroy() {
    this.handleInputChange = null;
  }
第二种 就是 timer等外层变量 作为全局变量

这样 就不会因为每次调用了都重置了 也不需要在组件去保留这个方法 只是作为全局 你要保证传入的时间内不会有第二个按钮被点击 不然依旧不会生效 因为 timer还存在

//公用方法里:
let timer;//放在公用方法外面 每次使用 都不会刷新
function debounce(fn, wait, immediate) {

}

如有更好的方式 欢迎指教

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值