Vue v-model:如何区分父组件与子组件对ref的修改来源
区分双向绑定中ref的修改来源
要实现区分父组件和子组件对双向绑定模型的修改,核心思路是利用Vue的单向数据流特性:父组件的修改会同步到子组件的props,而子组件内部的修改仅通过update:事件通知父组件,不会直接修改自身props。
方案一:监听原始props(推荐)
直接监听子组件接收的doc props,而非defineModel返回的ref。只有父组件的修改会触发props更新,子组件内部修改不会影响props,因此watch只会捕获父组件的变更:
<script setup> // Child.vue import { watch } from 'vue'; // 显式定义props(defineModel内部已包含此逻辑,仅为监听用) const props = defineProps(['doc']); const doc = defineModel('doc'); setTimeout(() => { // 子组件内部修改,不会触发props的watch doc.value = 'new inner value'; }, 3000); // 仅监听props的变化,对应父组件的修改 watch(() => props.doc, newValue => { console.log('捕获父组件修改:', newValue); }); </script>
方案二:使用标志位标记内部修改
如果需要基于defineModel的ref监听,可通过一个本地标志位标记子组件自身的修改,在watch回调中过滤:
<script setup> // Child.vue import { ref, watch, nextTick } from 'vue'; const doc = defineModel('doc'); const isSelfUpdating = ref(false); // 封装子组件内部修改的方法 const updateDocFromChild = () => { isSelfUpdating.value = true; doc.value = 'new inner value'; // 等待watch触发后重置标志 nextTick(() => isSelfUpdating.value = false); }; setTimeout(updateDocFromChild, 3000); watch(doc, newValue => { // 过滤子组件自身的修改 if (isSelfUpdating.value) return; console.log('捕获父组件修改:', newValue); }); </script>
两种方案都能实现需求,方案一更贴合Vue的数据流设计,代码更简洁;方案二则更灵活,适用于无法直接监听props的场景。
内容的提问来源于stack exchange,提问作者CMTV
相关产品推荐
相关产品推荐

