Subscribe on changes!

When using the `deep` mode of `watch`, `watchCallBack` will be triggered even if the value does not change.

avatar
Nov 17th 2022

Vue version

all (>=v3.2.16)

Link to minimal reproduction

Steps to reproduce

  1. Open Link to minimal reproduction
  2. Enter some spaces and watch the counter change

What is expected?

Do not call watchCallBack if the value has not changed; for example, if watch is listening for changes to an object in computed and the object's value is undefined for the next few changes, then watchCallBack should not be triggered.

The current behavior of watch in the above case leads to some hidden vulnerabilities that are hard to debug.

What is actually happening?

When using the deep mode of watch, watchCallBack will be triggered even if the value does not change.

System Info

No response

Any additional comments?

No response

avatar
Nov 17th 2022

Computed properties are lazily evaluated. So to know wether or not their value ha changed, the need to be read by some code. So effects depending on a computed property need to run in order to find out wether the return value has changed.

details: https://dev.to/linusborg/vue-when-a-computed-property-can-be-the-wrong-tool-195j

avatar
Nov 17th 2022

Computed properties are lazily evaluated. So to know wether or not their value ha changed, the need to be read by some code. So effects depending on a computed property need to run in order to find out wether the return value has changed.

details: https://dev.to/linusborg/vue-when-a-computed-property-can-be-the-wrong-tool-195j

I also found this, but it doesn't explain why turning on deep makes the watch function unable to determine if the value has changed; if it's an object, I can understand, but if the value of a variable becomes undefined or some other basic type at some point, why can't we simply use === to determine if it has changed to avoid this situation?

Inside watch it might be possible to solve this problem like this:

const needCallback = options.deep && typeof newValue === 'object'
 ? true
 : oldValue !== newValue
avatar
Nov 17th 2022

Thanks for the reply, I think I misunderstood your report. Reopened to investigate.

avatar
Oct 27th 2023

Fixed by #5912