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

如何让两个子组件同步更新同一个父组件属性?

问题描述

需要用复选框按类别过滤产品,创建父组件传递类别选项给子组件并维护选中状态。单个子组件运行正常,但添加第二个相同子组件(比如常规菜单和移动端菜单各一个)时,选中状态无法同步:在第一个子组件选类别“A”,第二个子组件的“A”复选框不会勾选。期望绑定同一个v-model实现同步,如何确保修改一个子组件时父组件更新且另一子组件状态同步?

父组件代码(Parent.vue)

<template>
  <FilterCheckboxItem
    ref="Category"
    name="Category"
    :FilterOptions="CategoryOptions"
    v-model="FilteredCategories"
  />
  <!-- 第二个子组件,绑定同一个v-model -->
  <FilterCheckboxItem
    ref="MobileCategory"
    name="MobileCategory"
    :FilterOptions="CategoryOptions"
    v-model="FilteredCategories"
  />
</template>

<script>
export default {
    data(){
        return {
          FilteredCategories: [],
          CategoryOptions: ["A","B","C"]
         }
    }
</script>

原小子组件代码(FilterCheckboxItem.vue)

<template>
<div
  v-for="FilterOption in FilterOptions"
>
  <input
    type="checkbox"
    :value="FilterOption"
    v-model="checked"
  />
</div>
</template>

<script>
export default {
    props: {
     FilterOptions: {
      type: Array,
    },
    modelValue: {
      type: Array,
    },
 },

  emits: ['update:modelValue'],


  setup(props, { emit }) {
    const checked = ref([]);
    watch(checked, (newVal) => {
      emit('update:modelValue', newVal);
    });
    return { emit, checked };
  },

</script>
解决方案

问题出在子组件内部的checked变量没有和父组件传递的modelValue做双向同步:子组件只监听了自身checked的变化并通知父组件,但没有监听父组件modelValue的变化来更新自身的checked状态。

修改后的子组件代码如下:

<template>
<div
  v-for="FilterOption in FilterOptions"
  :key="FilterOption" <!-- 添加key避免渲染问题 -->
>
  <input
    type="checkbox"
    :value="FilterOption"
    v-model="checked"
  />
</div>
</template>

<script>
import { ref, watch } from 'vue';

export default {
    props: {
     FilterOptions: {
      type: Array,
      required: true
    },
    modelValue: {
      type: Array,
      default: () => []
    },
 },

  emits: ['update:modelValue'],

  setup(props, { emit }) {
    const checked = ref([...props.modelValue]); // 初始化时同步父组件值

    // 监听自身checked变化,通知父组件
    watch(checked, (newVal) => {
      emit('update:modelValue', [...newVal]); // 传递新数组避免引用问题
    }, { deep: true });

    // 监听父组件modelValue变化,更新自身checked
    watch(() => props.modelValue, (newVal) => {
      checked.value = [...newVal];
    }, { deep: true });

    return { checked };
  },
};
</script>
关键修改点说明
  • 初始化同步:子组件的checked变量初始化时直接使用父组件传递的modelValue值,确保初始状态和父组件一致。
  • 监听父组件值变化:添加对props.modelValue的监听,当父组件的选中状态更新(比如另一个子组件修改后),立即同步更新自身的checked状态。
  • 添加deep: true:因为监听的是数组类型,需要开启深度监听才能捕获数组内部元素的变化。
  • 传递新数组:在通知父组件时,传递数组的副本([...newVal]),避免因为引用类型导致的意外问题。
  • 添加v-for的key:为循环的复选框元素添加唯一key,确保Vue正确追踪DOM元素,避免渲染异常。

这样修改后,两个子组件绑定同一个父组件的FilteredCategories,任意一个子组件修改选中状态,都会通过v-model同步到父组件,另一个子组件会监听父组件的变化自动更新自身的复选框状态,实现双向同步。

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:49:57