Vuejs.org: Add tip/work around when use a debounce function in a component's watch, the debounce function needs to be defined in the created event

Created on 15 Apr 2018  路  4Comments  路  Source: vuejs/vuejs.org

As discussed in the forum, a debounce function defined in a component's watch will not work as expected when there are multiple instances of the component. See example. The expected behavior is that the watch will fire the debounce function in all component instances, but it is only happening in one of the component instances.

The tip/work around is to define the debounce function in the component's created event instead of in the watch. See example. With this change, the watch fires the debounce function in all component instances.

Most helpful comment

@dtsao oh right, you're completely correct, my brain forgot that methods are shared too 馃槄

All 4 comments

Technically everything works as it should. Every component has the same function instance but is called with different context, so what happens in this case is you're calling the same debounce function across all components but with different context.

Short simplified example (changed debounce logic for simplification):

watcher: function debouncedFn(userFn) {
  let wasCalled = false;

  if (!wasCalled) {
    userFn.call(this);
    wasCalled = true;
  }
}

first component that triggers debouncedFn will execute it with debouncedFn.call(this, newValue, oldValue) etc.. which will set the wasCalled to true for all other components that also use this watcher, so every other call will be ignored.

You can go around this by creating a debounced method:

methods: {
  debouncedFn: _.debounce(function (newValue, oldValue) {
    // logic
  }),
},

and assign it to the watcher:

watch: {
  watchThis: 'debouncedFn',
},

which I think is more clear instead of defining it in data or created.

EDIT:; which seems the docs also show you about it in the methods part.

@donnysim, when I define the debouncedFn in a method instead of in the created event, the watch only updates one component instance. See example.

This is unfortunately, the same behavior as in my original example, where the debouncedFn was defined in the watch. Unless I am missing something, it still looks like the debouncedFn needs to be defined in the created event in order for the watch to call the function in all component instances.

@dtsao oh right, you're completely correct, my brain forgot that methods are shared too 馃槄

Closing as related PR was merged

Was this page helpful?
0 / 5 - 0 ratings

Related issues

emileber picture emileber  路  5Comments

philoyou11 picture philoyou11  路  4Comments

jgtorrejon picture jgtorrejon  路  5Comments

daymos picture daymos  路  4Comments

alexsasharegan picture alexsasharegan  路  3Comments