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

Vue 3父子组件复选框同步问题:如何获取所有选中项数组?

解决Vue3 + InertiaJS父子组件选中用户数组同步问题

1. 父组件(Create.vue)修改

首先确保父组件的checkedNames初始化为空数组,再通过v-model或自定义事件接收子组件的选中数组。

方式一:使用v-model双向绑定(推荐)

<script setup>
import { ref } from 'vue'
import UserSelector from '@/Components/UserSelector.vue'

// 初始化选中用户数组
const checkedNames = ref([])

// 表单提交逻辑示例
const submitForm = () => {
  console.log('选中的用户:', checkedNames.value)
  // 这里调用Inertia的提交方法,比如Inertia.post(route('xxx'), { checkedNames: checkedNames.value })
}
</script>

<template>
  <form @submit.prevent="submitForm">
    <!-- 其他表单字段 -->
    <UserSelector v-model="checkedNames" />
    <button type="submit">提交</button>
  </form>
</template>

方式二:使用自定义事件监听

<script setup>
import { ref } from 'vue'
import UserSelector from '@/Components/UserSelector.vue'

const checkedNames = ref([])

const updateSelectedUsers = (selectedList) => {
  checkedNames.value = selectedList
}
</script>

<template>
  <form @submit.prevent="submitForm">
    <UserSelector @update-selected="updateSelectedUsers" />
    <!-- 其他内容 -->
  </form>
</template>

2. 子组件(UserSelector.vue)修改

核心是维护子组件内部的选中数组,处理复选框的选中/取消逻辑,再同步给父组件。

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

// 接收父组件传递的v-model值(对应父组件的checkedNames)
const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  }
})

// 定义更新父组件的事件
const emit = defineEmits(['update:modelValue', 'update-selected'])

// 子组件内部维护选中数组,避免直接修改props
const selectedUsers = ref([...props.modelValue])

// 监听父组件的modelValue变化,同步到子组件内部
watch(() => props.modelValue, (newVal) => {
  selectedUsers.value = [...newVal]
}, { deep: true })

// 处理单个用户的选中/取消
const toggleUser = (userId) => {
  const index = selectedUsers.value.indexOf(userId)
  if (index > -1) {
    // 已选中,移除
    selectedUsers.value.splice(index, 1)
  } else {
    // 未选中,添加
    selectedUsers.value.push(userId)
  }
  // 同步到父组件(两种方式二选一)
  emit('update:modelValue', selectedUsers.value)
  // emit('update-selected', selectedUsers.value)
}

// 假设搜索得到的用户列表(实际根据你的搜索逻辑替换)
const searchedUsers = ref([
  { id: 1, name: '张三' },
  { id: 2, name: '李四' },
  { id: 3, name: '王五' }
])
</script>

<template>
  <div>
    <input type="text" placeholder="搜索用户" @input="handleSearch" />
    
    <table>
      <thead>
        <tr>
          <th>选择</th>
          <th>用户名</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="user in searchedUsers" :key="user.id">
          <td>
            <input
              type="checkbox"
              :checked="selectedUsers.includes(user.id)"
              @change="toggleUser(user.id)"
            />
          </td>
          <td>{{ user.name }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

关键注意事项

  • 必须确保父组件的checkedNames是数组类型,不能初始化为字符串或单个值。
  • 子组件处理复选框时,要执行添加/移除操作,而非直接赋值(这是你之前只能拿到最后一项的核心原因)。
  • 如果需要同步完整用户对象而非ID,只需把userId换成user,判断逻辑改为selectedUsers.some(u => u.id === user.id)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:40:40