Vue.js中子组件checkbox输入如何绑定到父组件的v-model
实现方案
核心原理
Vue 自定义组件实现双向绑定的默认约定:
- 组件接收名为
value的props,对应父组件v-model绑定的变量 - 组件值变更时向外触发
input事件,事件参数为最新值
针对多复选框共用一个选中数组的场景,我们需要在子组件中处理选中状态判断,变更时通知父组件完成数组的增删操作。
第一步:修正父组件代码
首先移除div上无效的v-model属性,将选中数组传递给子组件,同时绑定事件接收子组件的更新通知:
<!-- 原判断条件有问题:空数组为真值,需判断长度大于0才显示按钮 --> <button v-if="checkedNames.length > 0">Confirm</button> <div> <child-component v-for="person in collection" :key="person.id" :person="person" :checked-list="checkedNames" @update:checked="updateChecked" ></child-component> </div>
父组件实例新增更新选中数组的方法:
new Vue({ el: '...', data: { checkedNames: [], collection: [ {id: 1, name: 'Jack', items:[{id:100,name:"Pen",quantity:5}]}, {id: 2, name: 'John', items:[ {id:200,name:"Pen",quantity:10}, {id:201,name:"Paper",quantity:100} ]}, {id: 3, name: 'Mike', items:[{id:300,name:"Pen",quantity:20}]}, ] }, methods: { updateChecked(selectedItem) { // selectedItem结构:{ personId: 主ID, itemId: 子项ID, quantity: 子项数量, name: 子项名称 } const existsIndex = this.checkedNames.findIndex(item => item.itemId === selectedItem.itemId) if (existsIndex > -1) { // 已选中则移除 this.checkedNames.splice(existsIndex, 1) } else { // 未选中则新增 this.checkedNames.push(selectedItem) } } } })
第二步:修正子组件代码
子组件新增接收选中数组的props,给复选框绑定选中状态和变更事件:
<!-- 列表key改用唯一的item.id,避免索引重复导致渲染异常 --> <div v-for="(item, i) in person.items" :key="item.id"> <input type="checkbox" :id="item.id" :value="item.name" :checked="checkedList.some(selected => selected.itemId === item.id)" @change="handleCheckChange(item)" > <label :for="item.id">{{item.name}}</label> <!-- 数值输入框id加前缀避免和其他id重复 --> <input type="number" :id="`num-${item.id}`" :value="item.quantity" > <label :for="`num-${item.id}`">{{item.quantity}}</label> </div>
子组件实例新增事件抛出逻辑:
Vue.component('child-component', { props:{ person: Object, checkedList: Array }, methods: { handleCheckChange(item) { // 把所有需要的参数抛出给父组件 this.$emit('update:checked', { personId: this.person.id, itemId: item.id, quantity: item.quantity, name: item.name }) } } })
可选简化:直接绑定v-model
如果要直接在子组件上使用v-model语法,只需调整子组件的model配置,将props和事件名改成v-model默认约定的value和input即可,核心逻辑和上述方案一致。
内容的提问来源于stack exchange,提问作者Siona Fernandes
相关产品推荐
相关产品推荐

