如何正确实现Vue自定义Checkbox组件并解决调用时的报错问题
问题原因&解决方案
你的代码存在两处核心错误,直接导致了报错和警告:
错误1:错误的$emit传参
子组件Checkbox的change事件中,你将$emit函数本身作为参数传给了自定义事件do,完全不符合预期。同时你没有正确适配v-model的绑定逻辑,自定义组件要支持v-model必须符合Vue的约定规则。
错误2:复选框状态未绑定
你没有把传入的选中状态prop绑定到原生input的checked属性,也没有在状态变更时触发v-model对应的更新事件,导致双向绑定失效。
具体修改代码
子组件(Checkbox.vue)修改后代码
<template> <div class="filter"> <input :ref="id" :id="id" type="checkbox" class="filter-checkbox" :checked="isSelected" @change="handleChange" /> <!-- 优化为label标签,实现点击文字也能选中复选框 --> <label :for="id">{{ label }}</label> </div> </template> <script> export default { name: "Checkbox", // Vue2可保留该model配置适配v-model,Vue3环境可直接删除该配置 model: { prop: 'isSelected', event: 'update:isSelected' }, props: { label: { type: String }, isSelected: { type: Boolean }, id: { type: String } }, methods: { handleChange(e) { // 触发v-model更新事件,同步选中状态 this.$emit('update:isSelected', e.target.checked) // 触发自定义do事件,传入当前复选框id this.$emit('do', this.id) } } } </script>
父组件使用优化(可选)
子组件已经通过do事件返回了当前选中的复选框id,父组件可以直接接收参数,不需要在v-for中手动传递filter.id,写法更简洁:
<Checkbox v-for="filter of filters" :key="filter.id" :label="filter.name" :id="filter.id" v-model="filter.selected" @do="mutuallyExclusive" />
对应的父组件方法直接接收参数即可:
methods: { mutuallyExclusive(checkboxId) { // checkboxId即为当前点击的复选框id,直接写业务逻辑即可 } }
如果要保留原来的父组件传参写法也完全兼容,不会再出现报错。
内容的提问来源于stack exchange,提问作者Evgeny Alekseev
相关产品推荐
相关产品推荐

