Vue: Component is re-rendered when computed value stay same and its dep value changes.

Created on 18 May 2020  ·  5Comments  ·  Source: vuejs/vue

Version

2.6.11

Reproduction link

https://codesandbox.io/s/vue-computed-test-nc9s7?file=/src/App.vue

Steps to reproduce

Follow the link

What is expected?

The render function shouldn't be called when its dependent computed value isn't changed.

What is actually happening?

Every time the value changes, the component is re-rendered, even if the computed value is not changed.

Most helpful comment

We got the same problem, this is not obvious and very strange behaviour that components rerenders when computed property was not changed.
And there is performance issues because of this.
As a workaround we created watcher prop2 on computed prop1 and target prop2 in component

All 5 comments

This is working as expected: the render happens because the computed property is marked as dirty because it depends on value which changed. Vue calls again the render function because it depends on the computed property and needs to reevaluate the value

This is working as expected: the render happens because the computed property is marked as dirty because it depends on value which changed. Vue calls again the render function because it depends on the computed property and needs to reevaluate the value

So you can create another value value2 in data, then watch the value's change, set the value2's value at the true time, use value2 in render function

This is working as expected: the render happens because the computed property is marked as dirty because it depends on value which changed. Vue calls again the render function because it depends on the computed property and needs to reevaluate the value

I can understand it is by design. I wonder why if the value stays the same (which means ===) it is still conceptually be treated as 'dirty'? Of sure the computed value should be re-calculated, but the effect may be treated differently by its return value.

This is working as expected: the render happens because the computed property is marked as dirty because it depends on value which changed. Vue calls again the render function because it depends on the computed property and needs to reevaluate the value

I got the same problem. So I checked the createComputedGetter function here https://github.com/vuejs/vue/blob/v2.6.11/src/core/instance/state.js#L248.

function createComputedGetter (key) {
  return function computedGetter () {
    const watcher = this._computedWatchers && this._computedWatchers[key]
    if (watcher) {
      if (watcher.dirty) {
        watcher.evaluate()
      }
      if (Dep.target) {
        // look at here
        watcher.depend()
      }
      return watcher.value
    }
  }
}

And find that a component depends on computed value would being proxied to depend on the computed's deps. So, when a computed's dep changed the component will re-render. A computed property is marked as dirty would only trigger computed's getter being re-evaluated but not the render. Am I right? If so, I think this is incorrect because my render is just depend on the computed value not the computed's dep value. And my true purpose of using computed is to ignore some unnecessary re-render.

We got the same problem, this is not obvious and very strange behaviour that components rerenders when computed property was not changed.
And there is performance issues because of this.
As a workaround we created watcher prop2 on computed prop1 and target prop2 in component

Was this page helpful?
0 / 5 - 0 ratings