You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 05:48:29