const allChecked = rows.every(r => r.checked);
const someChecked = rows.some(r => r.checked);
allBox.checked = allChecked;
allBox.indeterminate = someChecked && !allChecked;

列表有 12 行,点了全选全部勾上,取消其中一行后,表头的全选框仍然是勾选状态。再点一次全选,反而把剩下的全取消了。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,全选框只写了点击时同步子项,子项变化时没有反向更新表头。全选框的 checked 变成了独立状态,和实际选中数量脱钩。

围绕「全选联动」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。

处理上按这个顺序:全选框的选中状态由子项数组实时推导,不单独存一份;子项变化后重算是否全选和是否半选;半选状态用 indeterminate 表示,和全选区分开。

改完只确认一件事:全选后取消任意一行,表头全选框变成半选;全部取消后半选也消失。

作者 9823189