Vue如何编写防抖(debounce)和节流(throttle)函数

关键点:

  • vue写法与普通有点差异,因为vue的this不仅仅是当前的组件对象,还往上继承了vue对象(下文可以看出差异)
  • call ,apply都只能继承父级,并不能深度继承
  • 因为深度继承需要递归或者多层嵌套函数,代码量大且难维护,因此推荐下方方法

1.防抖(debounce)

  • 含义:触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。

是个连续的过程 ,如限制1s,执行一次,到下次执行又是1s,即:用户停下操作,就执行函数;只要不停止操作,永远不会执行函数内的操作

  • 使用场景:防抖常应用于用户进行搜索输入节约请求资源,window触发resize事件时进行防抖只触发一次
  • 代码:
/**
 * @description 函数防抖 触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。
 * @param {Function} func 需要执行的函数
 * @param {Number} wait 间隔时间 默认200ms
 * @param {Boolean} immediate  是否立即执行 true(默认) 表立即执行,false 表非立即执行
 * @return {*}
 * @author liuxin
 */
export function VueDebounce(func, wait = 200, immediate = true) {
    let timeout = null;  // 定时器
    return function () {
        let that = this, // this对象
            args = arguments; // 参数
        if (timeout) clearTimeout(timeout);
        if (immediate === true) { // 立即执行
            var callNow = !timeout;
            timeout = setTimeout(() => {
                timeout = null;
            }, wait)
            if (callNow) {
                // func.apply(that, args); // 普通用法 vue3用法
                that[func](...args); // vue2用法
            }
        }
        else { // 非立即执行
            timeout = setTimeout(() => {
                // func.apply(this, args); // 普通用法 vue3用法
                that[func](...args); // vue2用法
            }, wait);
        }
    }
}
  • 用法Vue2


methods: {
    /**
     * 点击事件 函数防抖
     * 用法:<el-button @click="debounceHandel">点击测试</el-button>
     */
    debounceHandel: VueDebounce("handlerFunc"),

    /**
     * 点击事件:真正执行的函数
     */
    handlerFunc(type) {
      console.log("测试防抖事件");
      this.$emit("click","这是参数"); // 如果用普通用法,则这里会找不到$emit,因为this还往上继承了vue的对象
    },
  }

  • 用法vue3

<el-button type="primary" size="default" @click="cleanHandle">测试防抖</el-button>

export default {
  setup() {
    const state = reactive({
    });

    /**
     * @description: 一秒执行一次
     * @Author: liuxin
     */
    const cleanHandle = VueDebounce(() => {
      scoket.send(
        JSON.stringify({
          api: "clear_count",
        })
      );
    }, 1000);

    return {
      ...toRefs(state),
      cleanHandle,
    };
  },
};

2.节流(throttle)

  • 含义:高频时间触发,但n秒内只会执行一次,所以节流会稀释函数的执行频率。。是个固定的过程 ,如限制1s,则1s内只执行一次,无论怎样,都在会1s内执行相应的操作
  • 使用场景:和防抖使用场景差不多,关键看固定时间内(1s)需要反馈,需要反馈使用节流,即:无论用户是否停下操作,都会固定时间执行函数操作
  • 代码:用法与函数防抖一致
import { ElMessage } from "element-plus";
import "element-plus/es/components/message/style/css"
/**
 * @description 函数节流
 * @param {Function} func 函数
 * @param {Number} wait 延迟执行毫秒数,默认200
 * @param {Number} type 1 表时间戳版,2 表定时器版
 */
function VueThrottle(func, wait=200 ,type) {
    if(type===1){
        let previous = 0;
    }else if(type===2){
        let timeout;
    }
    return function() {
        let that= this;
        let args = arguments;
        if(type===1){
            let now = Date.now();

            if (now - previous > wait) {
                // func.apply(that, args); // 普通用法
                that[func](...args); // vue用法
                previous = now;
                ElMessage.closeAll(); // 关闭所有弹窗
            }
            else {
                ElMessage.error("操作太频繁了哦,稍后再试");
            }
        }else if(type===2){
            if (!timeout) {
                timeout = setTimeout(() => {
                    timeout = null;
                    // func.apply(that, args)
                    that[func](...args); // vue用法
                    ElMessage.closeAll();// 关闭所有弹窗
                }, wait)
            }
            else {
                ElMessage.error("操作太频繁了哦,稍后再试");
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/liuxin00020/article/details/109229212