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

Vue3父子组件双向绑定后父组件watch监听对象不触发如何解决?

问题原因

  1. Vue默认的watch监听为浅层监听,仅会在被监听变量的引用本身发生替换时触发。你当前是修改record对象的内部属性,record的引用没有变化,因此默认watch不会触发。
  2. 当前子组件直接修改props传入的对象属性,违反了Vue单向数据流规范,虽然因为对象是引用类型可以实现视图同步,但属于不符合规范的写法,后续维护容易出现不可预期的问题。
  3. 你父组件的data写法存在语法错误,需要返回对象,否则record不会被正确声明为响应式属性。

解决方法

方案1:最小改动适配(快速生效)

给父组件的watch配置开启深度监听,同时修复data的语法错误:

<!-- parent.vue 修正后代码 -->
<script lang="ts">
export default {
  data() {
    // 修正data返回对象的语法
    return {
      record: undefined
    }
  },
  created() {
    // 获取record的代码
    this.record = new Record(responseJson);
  },
  watch: {
    record: {
      handler: function(newRecord, oldRecord) {
        alert("change detected!");
        // 子组件修改record时执行对应逻辑
      },
      // 开启深度监听,内部属性变更也会触发回调
      deep: true
    }
  }
}
</script>

方案2:符合单向数据流规范的标准写法(更推荐)

子组件通过计算属性封装v-model逻辑,修改时主动抛出更新事件,符合Vue数据流向规范:

<!-- child.vue 修正后代码 -->
<template>
  <InputText v-model="localRecord.title"></InputText>
  <InputText v-model="localRecord.description"></InputText>
</template>

<script lang="ts">
export default {
  props: {
    record: {
      type: Object as () => RecordModel,
      required: true
    }
  },
  emits: ["update:record"],
  computed: {
    localRecord: {
      get() {
        return this.record
      },
      set(val) {
        // 抛出更新事件,由父组件完成属性更新
        this.$emit('update:record', val)
      }
    }
  }
}
</script>

该方案不需要额外开启深度监听,父组件的record引用会在子组件抛出事件时被替换,原生触发watch回调。

内容的提问来源于stack exchange,提问作者John D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:57:03