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

Vue3 Script Setup自定义子组件多复选框v-model双向绑定问题

Vue3 自定义多复选框组件双向绑定实现方案

错误原因解析

你遇到的Invalid prop报错,是因为子组件的SelectedItems prop类型定义错误(写成了Object),但实际需要绑定的是数组类型;同时v-model的双向绑定逻辑未正确处理,导致传入值类型异常。

实现代码

父组件(使用示例)

<template>
  <CheckboxGroup 
    v-model:selected-items="selectedItems"
    v-model:is-check-all="isCheckAll"
    :options="options"
  />
</template>

<script setup>
import { ref } from 'vue'
import CheckboxGroup from './CheckboxGroup.vue'

// 绑定的选中项数组
const selectedItems = ref([])
// 全选状态
const isCheckAll = ref(false)
// 复选框选项数据
const options = ref([
  { id: 1, label: '选项1' },
  { id: 2, label: '选项2' },
  { id: 3, label: '选项3' },
  { id: 88, label: '选项88' }
])
</script>

子组件(CheckboxGroup.vue)

<template>
  <div>
    <!-- 全选复选框 -->
    <label>
      <input 
        type="checkbox" 
        :checked="isCheckAll"
        @change="handleCheckAllToggle"
      >
      全选
    </label>
    <!-- 单个选项复选框 -->
    <div v-for="option in options" :key="option.id" class="item">
      <label>
        <input 
          type="checkbox" 
          :value="option.id"
          :checked="selectedItems.includes(option.id)"
          @change="handleItemToggle(option.id)"
        >
        {{ option.label }}
      </label>
    </div>
  </div>
</template>

<script setup>
// 定义props,注意类型匹配
const props = defineProps({
  selectedItems: {
    type: Array,
    default: () => []
  },
  isCheckAll: {
    type: Boolean,
    default: false
  },
  options: {
    type: Array,
    required: true
  }
})

// 定义触发父组件更新的事件
const emit = defineEmits(['update:selected-items', 'update:is-check-all'])

// 单个选项选中状态变更处理
const handleItemToggle = (id) => {
  // 生成新数组(不可直接修改props)
  const newSelected = [...props.selectedItems]
  if (newSelected.includes(id)) {
    // 移除已选中项
    newSelected.splice(newSelected.indexOf(id), 1)
  } else {
    // 添加选中项
    newSelected.push(id)
  }
  // 触发父组件更新选中数组
  emit('update:selected-items', newSelected)
  // 同步更新全选状态
  emit('update:is-check-all', newSelected.length === props.options.length)
}

// 全选状态变更处理
const handleCheckAllToggle = (e) => {
  const isChecked = e.target.checked
  // 触发父组件更新全选状态
  emit('update:is-check-all', isChecked)
  // 触发父组件更新选中数组(全选时取所有选项id,取消时清空)
  emit('update:selected-items', isChecked ? props.options.map(item => item.id) : [])
}
</script>

核心注意事项

  1. Prop类型匹配:selectedItems必须定义为Array类型,避免类型不匹配报错
  2. Vue3多v-model语法:通过v-model:prop-name(短横线命名)绑定多个双向数据,子组件通过update:prop-name事件触发父组件更新
  3. 数组响应式处理:修改选中项时必须返回新数组,不能直接修改props数组,保证响应式生效
  4. 状态同步:单个选项变更后要同步判断全选状态,全选操作直接覆盖选中数组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:05:30