多选框组件用 emit 传递状态是为了遵循单向数据流,子组件通过 update:modelValue 事件将新选中数组抛给父组件统一维护。子组件基于当前 modelValue 计算新数组并 emit,避免直接修改原数组导致响应失效;父组件用 v-model 或 @update:model-value 接收更新。

多选框组件为什么要用 emit 传递状态
多选框组件(如自定义的 CheckboxGroup)通常封装了内部选中状态和渲染逻辑。父组件需要知道哪些选项被选中、何时变化,但又不能直接修改子组件 data —— 这违背 Vue 的单向数据流原则。所以子组件通过 $emit('update:modelValue', [...]) 或自定义事件(如 change)把最新选中项数组抛给父组件,由父组件统一维护状态,实现响应式同步。
如何用 emit 正确同步多选数组
关键在于:子组件不保存“全量选中状态”,只管理当前点击项与已有状态的增减关系,并把结果数组 emit 出去。
- 子组件接收 v-model 绑定的数组(如
modelValue: { type: Array, default: () => [] }) - 每个 checkbox 点击时,基于当前 modelValue 计算新数组:
✅ 已存在 → 过滤掉(取消)
❌ 不存在 → concat 追加(勾选) - 调用 this.$emit('update:modelValue', newArray)(Vue 2)或 emit('update:modelValue', newArray)(Vue 3)
避免常见坑:数组引用与响应式失效
直接 push / splice 原数组可能触发不了视图更新(尤其在 Vue 2 中),或导致父组件无法监听变化。务必用生成新数组的方式:
- ❌ 错误:
this.modelValue.push(val); this.$emit('change', this.modelValue); - ✅ 正确(Vue 2/3 通用):
const next = this.modelValue.includes(val) ? this.modelValue.filter(v => v !== val) : [...this.modelValue, val]; this.$emit('update:modelValue', next); - Vue 3 推荐使用 defineModel 简化写法(需启用实验性特性),但 emit 方式兼容性更广
父组件如何配合接收并更新
父组件用 v-model 绑定即可自动响应(Vue 2.7+ / Vue 3),或显式监听 + 同步赋值:
立即学习“前端免费学习笔记(深入)”;
- Vue 3 模板:
<CheckboxGroup v-model="selectedList" :options="list" /> - Vue 2 模板:
<CheckboxGroup :model-value="selectedList" @update:model-value="selectedList = $event" :options="list" /> - 确保 selectedList 是响应式 ref / data 属性,且初始值为数组(不能是 null 或 undefined)










