Multiple source watcher fires sideEffect every time after watching sources has been evaluated
Version
3.0.11
Steps to reproduce
- App.vue
<template>
<child :foo="foo"></child>
</template>
<script lang="ts">
import { reactive } from 'vue';
import Child from './Child.vue';
export default {
components: { Child },
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setup(): any {
const vm = (window.vm = reactive({
window,
foo: [false, false]
}));
return vm;
}
};
</script>
<style scoped lang="scss"></style>
- Child.vue
<template>
<label>test</label>
</template>
<script lang="ts">
import { onBeforeMount, onMounted, reactive, onBeforeUpdate, watch, onUpdated } from 'vue';
export default {
props: ['foo'],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setup(props: any): any {
const vm = reactive({});
onBeforeMount(() => {
watch([() => props.foo.some((x: any) => x)], () => { console.log('mutated'); });
});
return vm;
}
};
</script>
<style scoped lang="scss"></style>
- open console and add item into
App
'svm.foo
by executingvm.foo.push(false);
What is expected?
Since before and after have same evaluation result: false
, suppose sideEffect will not be fired.
What is actually happening?
The sideEffect has been fired and log message is displayed.
If we change the watcher line
from watch([() => props.foo.some((x: any) => x)], () => { console.log('mutated'); });
to watch(() => props.foo.some((x: any) => x), () => { console.log('mutated'); });
It works, same result before and after won't fired the sideEffect again.
How can I avoid this case if I really need to use multiple source watcher?
Duplicate of https://github.com/vuejs/vue-next/issues/3068