3.0.0
https://jsfiddle.net/mravLjd6/4/
Open console and watch output
Only one log message "true false"
Log fired every second with "false false"
const { computed, watch, ref } = Vue;
const source = ref(0);
const isZero = computed(() => source.value === 0);
watch(isZero, (prev, next) => console.log(prev, next)); // fires every second
setInterval(() => source.value++, 1000);
This is part from docs(https://v3.vuejs.org/guide/reactivity-computed-watchers.html#watch):
The watch API is the exact equivalent of the component watch property. watch requires watching a specific data source and applies side effects in a separate callback function. It also is lazy by default - i.e. the callback is only called when the watched source has changed.
I think this is intended as it allows to trigger a watcher whenever a computed is reevaluated. You can still only pay attention to the value by doing:
watch(() => isOdd.value, (prev, next) => console.log(prev, next));
Oh, i get it. Thank you, it may be closed then
It makes more sense to me that the watch is triggeret only two times, one with (true, true) and (true, false). Why is it implemented this way?. In other words, watch does not perform any comparation in the values?
The same behaviour with watchEffect
const { computed, watchEffect, ref } = Vue;
const source = ref(0);
const isZero = computed(() => source.value === 0);
watchEffect(() => console.log(isZero.value)); // fires every second
setInterval(() => source.value++, 1000);
with watchEffect() it's expected. Since computed properties are evaluated lazily(*), the effect has to run in order to determine whether or not the value of isZero did change.
However for the watch(), we could check that the old & the new value are in fact different before calling the callback function.
Here we basically assume that if it's a ref, the value definitely has changed and we can call the callback.
The issue is that a computed ref also counts as a ref, but it doesn't neccessarily have a changed value.
So I think we can simply remove the || isRefSource condition here, that should fix it.
Most helpful comment
with watchEffect() it's expected. Since computed properties are evaluated lazily(*), the effect has to run in order to determine whether or not the value of
isZerodid change.However for the watch(), we could check that the old & the new value are in fact different before calling the callback function.