用 computed 实现全选/反选:全选框 v-model 绑定计算属性,get 判定是否全选,set 批量更新子项;通过 :indeterminate 绑定半选状态;反选直接遍历取反;key 须用唯一 id,确保响应式。

用 computed 实现全选/反选,核心是把“是否全选”和“是否半选”这两个状态,从原始数据中自动推导出来,而不是手动维护。Vue 的响应式系统会自动更新,逻辑更清晰、不易出错。
全选状态由子项决定,而非反过来
不要在点击全选框时遍历所有子项去设 checked,而是让全选框的 v-model 绑定到一个计算属性上——这个属性的 get 返回“是否全部勾选”,set 负责批量更新子项。
-
get:检查所有子项的
checked是否都为true -
set:把所有子项的
checked设为传入的新值(true或false)
支持“半选”状态(indeterminate)
当部分子项被选中时,全选框应显示为中间态(小横线)。这不能靠 v-model 实现,需用原生 indeterminate 属性:
- 用另一个计算属性判断是否“部分选中”(即:有选中 + 有未选中)
- 在全选 checkbox 上绑定
:indeterminate="isIndeterminate" - 注意:
indeterminate是只读视觉状态,不影响v-model值
反选只需一行逻辑,无需额外方法
反选按钮的本质,就是把每个子项的 checked 取反。可以直接写成一个方法,但更推荐封装为计算属性的 setter 或独立方法:
- 定义
toggleAll方法:遍历子项,item.checked = !item.checked - 如果用了
computed全选绑定,反选后会自动触发全选框状态更新(因为依赖变了) - 不需要手动同步全选框,响应式会帮你完成
避免常见坑:数组索引变化导致响应失效
如果子项列表是通过 v-for 渲染且使用 index 作为 key,排序或过滤后可能造成 checkbox 状态错位。务必:
- 用唯一、稳定字段做
key(如:key="item.id") - 确保子项对象本身是响应式的(用
ref或reactive包裹) - 不要直接替换整个子项数组,改用
splice或push等变异方法(或用ref+ 赋值)










