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>
核心注意事项
- Prop类型匹配:
selectedItems必须定义为Array类型,避免类型不匹配报错 - Vue3多v-model语法:通过
v-model:prop-name(短横线命名)绑定多个双向数据,子组件通过update:prop-name事件触发父组件更新 - 数组响应式处理:修改选中项时必须返回新数组,不能直接修改props数组,保证响应式生效
- 状态同步:单个选项变更后要同步判断全选状态,全选操作直接覆盖选中数组
内容的提问来源于stack exchange,提问作者SGA
相关产品推荐
相关产品推荐

