I am trying to create two-way binding but the problem is that I need to know what exactly changes the model ref: parent or child component.
When using watch it simply catches all changes and I can’t find the way to distinguish the source of change.
<script setup>
// Parent.vue
const doc = ref('');
setTimeout(() => {
// Update this ref AND trigger watch in Child.vue
doc.value = 'new value from parent';
}, 2000);
</script>
<template>
<Child v-model:doc="doc" />
</template>
<script setup>
// Child.vue
const doc = defineModel('doc');
setTimeout(() => {
// DO NOT TRIGGER WATCH ON THIS ONE!
// But still update parent `doc` ref
doc.value = 'new inner value';
}, 3000);
watch(doc, newValue => {
// Catch `new value from parent` but not `new inner value`
});
</script>
>Solution :
Use a flag in the child:
<script setup>
import {watch} from 'vue';
const doc = defineModel('doc');
let meChangingDoc = false;
setTimeout(() => {
// DO NOT TRIGGER WATCH ON THIS ONE!
// But still update parent `doc` ref
meChangingDoc = true;
doc.value = 'new inner value';
}, 3000);
watch(doc, newValue => {
if(meChangingDoc) {
meChangingDoc = false;
console.log('child changed doc');
return;
}
console.log('parent changed doc')
// Catch `new value from parent` but not `new inner value`
});
</script>