您的位置:

Vue节流的原理及应用

一、Vue节流方法

Vue的节流方法是指在某个时间间隔内只执行一次函数。这个方法适用于那些需要频繁触发的 DOM 事件函数,如scroll,mousemove等。节流的原理是设置一个定时器,在定时器内执行函数,每次函数执行完毕后清除定时器,再次触发时重新设置定时器。

二、Vue节流封装

Vue的节流可用以下封装代码,这样就可以直接在 Vue 实例中调用:

Vue.prototype.$throttle = function(fn, delay) {
  let lastTime = 0;
  return function() {
    let nowTime = new Date().getTime();
    if (nowTime - lastTime > delay) {
      fn.apply(this, arguments);
      lastTime = nowTime;
    }
  };
};

使用时可以这样:

// 定义事件函数
function handleScroll() {
  console.log("scrolling");
}
// 传入事件函数和时间间隔
window.addEventListener("scroll", this.$throttle(handleScroll, 1000));

三、Vue节流防抖

Vue的节流防抖是指在函数触发后,在规定时间之内再次触发将被忽略。这个方法适用于那些频繁触发的函数事件,如输入框的输入事件,对于一些用户需要输入,但是输入过快会导致频繁的数据更新请求,可以使用节流防抖以减少请求次数。

防抖的原理是使用 setTimeout 函数,每次触发时清除一个定时器,如果在指定时间间隔内再次触发则重新设置定时器。

Vue.prototype.$debounce = function(fn, delay) {
  let timer = null;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
};

使用时可以这样:

// 定义事件函数
function handleInput() {
  console.log("inputting");
}
// 传入事件函数和时间间隔
this.$refs.input.addEventListener("input", this.$debounce(handleInput, 500));

四、Vue节流阀

Vue的节流阀是一个很实用的功能,主要用于控制短时间内多次请求。它可以控制一段时间内最多可以请求几次,达到限制后会自动暂停。这个功能适用于那些用户触发频率高,但是并不需要每个都更新后端数据的情况,适用于推荐列表,热门搜索等。

Vue.prototype.$createThrottleValve = function(limitCount, limitTime) {
  const records = [];
  let timer = null;
  return function(fn) {
    const now = Date.now();
    records.push(now);
    if (records.length > limitCount) {
      const removeCount = records.findIndex(
        (time) => now - time < limitTime
      );
      records.splice(0, removeCount);
    }
    if (records.length >= limitCount) {
      clearTimeout(timer);
      const firstTime = records[0];
      const diffTime = limitTime - (now - firstTime);
      timer = setTimeout(() => {
        fn();
      }, diffTime);
      return;
    }
    fn();
  };
}

使用时可以这样:

// 定义事件函数
function handleHotSearch() {
  console.log("request hot search");
}
// 传入事件函数和请求限制
const throttleValve = this.$createThrottleValve(5, 1000);
this.$refs.hotSearch.addEventListener("click", function() {
  throttleValve(handleHotSearch);
});

五、Vue节流只执行最后一次接口

Vue的节流还可以只执行最后一次接口。这个方法适用于在一些需要连续触发请求的场景下,只需要保留最后一次的数据更新即可。还是使用 setTimeout 函数来实现的,但是需要注意到如果设置间隔时间太短则不会执行两次,需要根据实际场景调整时间。

Vue.prototype.$onlyLastReq = function(fn, delay) {
  let timer = null;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
};

使用时可以这样:

// 定义事件函数
function handleUpdate() {
  console.log("request update");
}
// 传入事件函数和时间间隔
window.addEventListener("scroll", this.$onlyLastReq(handleUpdate, 500));

六、Vue节流指令

对于一些频繁触发的 DOM 事件,还可以使用 Vue 的自定义指令来实现节流。在注册指令时可以通过参数传入时间间隔,对于同一 DOM 元素,限制时间间隔内只能被触发一次。

Vue.directive('throttle-click',{
  inserted:function(el,binding){
    let delay = binding.arg || 600
    let timer
    el.addEventListener('click', () => {
      if(!timer){
        timer = setTimeout(() => {
          timer = null
          binding.value()
        }, delay)
      }
    })
  }
})

使用时可以这样:


七、Vue节流防抖插件

Vue还有很多优秀的开源插件可供使用,其中就有很多封装了 Vue 的节流或防抖功能。

如 lodash 的 debounce 函数:

import _ from 'lodash'

export default {
  methods:{
    handleClick: _.debounce(function(){
      console.log('click')
    }, 1000)
  }
}

使用时可以这样:


八、Vue节流按钮

Vue 的节流按钮是一个非常实用的功能,可以在限制时间内防止按钮重复点击。可以使用组件封装的方式来实现节流按钮。

  

<script>
export default {
  props: {
    handler: { type: Function, required: true },
    delay: { type: Number, default: 300 },
    text: { type: String, default: "Click" },
  },
  data() {
    return {
      isThrottling: false,
    };
  },
  computed: {
    buttonText() {
      return this.isThrottling ? `${this.text}ing...` : this.text;
    },
  },
  methods: {
    runHandler() {
      if (!this.isThrottling) {
        this.isThrottling = true;
        this.handler();
        setTimeout(() => {
          this.isThrottling = false;
        }, this.delay);
      }
    },
  },
};
</script>

使用时可以这样:

  

九、Vue节流函数失效选取

在使用 Vue 的节流或防抖方法时,需要根据不同实际情况和业务需求选择不同的节流方法,避免出现无效操作和效果不佳的情况。

节流方法的间隔时间不能过长或过短,过长会影响用户的体验,过短会导致触发事件太频繁,失去节流效果。

防抖方法的间隔时间也不能过长或过短,过长会导致用户输入有延迟的感觉,过短则会导致多次请求,降低性能。

同时,需要根据实际业务需求选择节流阀或只保留最后一次接口等方法,避免频繁请求和更新。

总结

Vue提供了多种节流防抖方法和插件,可以用来优化用户体验和提高性能。需要根据实际业务需求选择不同的节流方法,避免出现无效操作和效果不佳的情况。