Vue.js 如何让去抖功能独立作用于同一组件的不同实例?

How to make a debounce function act independently on different instances of the same component on Vue.js?

我有两个 Vue 组件,它们对每次数据更改都有一个 "save to disk" 调用,它通过混合加载到这些组件中,每个组件保存到不同的文件中,因此它们必须独立运行(仅根据其自身的数据更改触发去抖重置)。防止过多写入磁盘。这是我的 debound 函数:

function debounce(fn, delay) {
  var timeoutID = null;
  return function () {
    console.log("clearing " + timeoutID)
    clearTimeout(timeoutID);
    var args = arguments;
    var that = this;
    timeoutID = setTimeout(() => fn.apply(that, args), delay);
  };
}

这是组件继承的我的 mixin 上的方法:

  methods: {
    saveData: debounce(function(){
        console.log('saving widget: ' + this.$parent.widget.id);
        this.saver.store = this.persisted;
    }, 5000),
  },

当我在一个或另一个组件上更改数据时它工作得很好,但是当我更改一个组件上的数据并且在去抖结束之前我更改另一个组件时,它取消了我从第一个组件开始的去抖功能,并且只保存第二个组件数据。

我在这里错过了什么?

这是因为每个组件实例共享相同的去抖功能,只有上下文(thisthat)不同。

一个简单的解决方法是将去抖实现更改为


function debounce(fn, delay) {
  var thatUidToTimeoutID = {};
  return function () {
    var args = arguments;
    var that = this;
    clearTimeout(thatUidToTimeoutID[that._uid]);
    thatUidToTimeoutID[that._uid] = setTimeout(() => fn.apply(that, args), delay);
  };
}

_uid 持有每个组件的唯一 ID,它更像是一个内部 属性(因此它是奇怪的键)但它应该足够好。

我今天遇到了同样的问题。我尝试了其他方法,在我看来,它更干净一些。不要像您那样在方法块中定义 debounced 函数,而是尝试将其定义为数据的一部分,如下所示:

  data() {
   return {
    saveData: debounce(function(){
        console.log('saving widget: ' + this.$parent.widget.id);
        this.saver.store = this.persisted;
    }, 5000)
  }
 }

您可以像往常一样调用该方法。来自文档:“组件的数据选项必须是一个函数,这样每个实例都可以维护返回数据对象的独立副本。”这样,每个使用 debounce 函数的实例都将拥有它自己的唯一实例。

可在此处找到有关其工作原理的更多信息:https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function