切换日光/暗黑模式
092. 单选、多选、列钩子与行事件钩子
学习目标
这一节开始实现单选、多选,并引入事件钩子。
学完后,你应该能理解:
- 单选为什么和表单编辑有关;
- 多选为什么会影响批量操作和父子表;
- 列配置为什么也要变成钩子变量;
- 查询表单显示为什么要放进配置;
- 事件钩子如何替代统一 handler;
- 为什么点击按钮或输入框时不能触发行点击事件。
单选的作用
表格单选不是只为了选中一行。
它还会服务很多后续功能。
例如:
- 表单编辑;
- 查看详情;
- 父子表联动;
- 当前行上下文;
- 外部按钮操作当前行。
如果表单编辑按钮不放在每一行里,就需要通过单选拿到当前行。
所以单选能力是表单编辑服务的前置基础。
单选默认开启
单选会和索引列融合。
也就是说,不一定单独再加一列显示单选。
索引列既可以显示序号,也可以承载当前行选中状态。
这样表格不会多出一列,视觉更紧凑。
单选默认强制开启,是因为后面很多功能都依赖当前行。
多选的作用
多选用于批量操作。
例如:
- 批量删除;
- 批量导出;
- 批量编辑;
- 智能新建时选择多条参考数据。
多选也可以影响父子表。
当主表选中行发生变化时,子表可以根据当前选中行重新加载数据。
所以单选和多选都不是孤立功能。
它们是表格状态体系的一部分。
列也需要钩子变量
前面已经有:
- 渲染钩子;
- 按钮钩子变量。
这一节继续把列配置也变成钩子变量。
原因是不同模块可能都要往表格里加列。
例如:
- 索引列模块添加索引列;
- 多选模块添加选择列;
- 操作列模块添加操作列;
- 业务模块添加自定义列。
如果列只来自页面配置,就无法让模块灵活插入系统列。
列顺序 seq
列配置里有 seq。
它控制列显示顺序。
默认值可以是 0。
左固定列和右固定列还可以自动调整顺序。
大致规则是:
- 越小越靠左;
- 越大越靠右;
- 左固定列适合更小顺序;
- 右固定列适合更大顺序。
这样索引列、选择列、操作列都能按稳定顺序插入。
查询表单显示配置
查询表单模块增加了显示控制。
例如:
- 是否默认展开查询表单;
- 是否显示查询表单按钮。
默认可以不展开。
页面配置里可以开启。
这样不同页面可以决定查询表单是否默认出现。
如果某个页面不需要查询按钮,也可以通过配置隐藏。
事件钩子
表格里很多模块都可能需要监听行事件。
例如:
- 双击行进入编辑;
- 单击行选中;
- 点击行刷新子表;
- 点击行触发详情展示。
如果都写到一个统一 handler 里,后面会越来越臃肿。
所以引入事件钩子。
每个模块监听自己关心的事件。
事件钩子的结构
事件钩子内部维护一个函数数组。
每个监听者往数组里注册自己的处理函数。
例如:
ts
autoTable.hooks.onClickRow.use(handler)
autoTable.hooks.onDoubleClickRow.use(handler)当事件发生时,事件钩子依次执行这些 handler。
这和 Axios 拦截器有点像。
一组函数按顺序处理同一个事件数据。
监听函数的参数类型
行点击事件需要传递几个信息:
- 鼠标事件;
- 行数据;
- 行索引。
所以事件参数可以理解成:
ts
{
event: MouseEvent
record: RowData
index: number
}监听函数接收到这些数据后,就能做自己的业务逻辑。
例如编辑、选中、刷新子表。
注册和清理监听函数
事件钩子使用 useEffect 维护监听函数。
当传入的 handler 变化时:
- 把新的 handler 放进数组;
- 在清理函数里移除旧 handler。
这样组件卸载或依赖变化后,不会留下旧监听。
否则同一个事件可能被重复触发多次。
双击编辑迁移到事件钩子
原来双击行进入编辑,是通过统一 handler 模块处理。
现在可以改成事件钩子。
状态模块或编辑模块监听 onDoubleClickRow。
触发时判断配置:
ts
if (runningConfig.editRowOnDoubleClick) {
autoTable.methods.editRecord(record)
}这样双击编辑变成一个模块行为。
以后其他模块也可以监听同一个双击事件。
统一 handler 可以移除
引入事件钩子后,统一 handler 模块的职责会变少。
行组件只负责派发事件。
具体谁响应事件,由各个模块自己决定。
这样模块之间更解耦。
新增功能时,不需要持续修改一个越来越大的 handler 文件。
行组件派发事件
表格行组件监听原生点击和双击。
触发后,它把事件数据交给事件钩子。
例如:
ts
autoTable.hooks.onClickRow.exec({
event,
record,
index,
})双击同理。
这样行组件不关心点击之后具体做什么。
它只负责把事件发出去。
忽略按钮和输入框点击
点击表格行时,要排除一些元素。
例如:
- 按钮;
- 输入框。
如果用户双击按钮,不应该触发行双击编辑。
如果用户点击输入框,也不应该触发行选择或行编辑。
所以事件派发前,要检查点击目标。
如果目标元素是 button 或 input,就直接跳过。
这能避免很多交互误触。
事件钩子的执行结果
事件钩子后面还会更复杂。
它可以把上一个函数的执行结果传给下一个函数。
这要求监听函数的入参和出参类型一致。
这种设计可以让事件数据经过多个模块逐步加工。
当前先理解最基础的监听和派发即可。
后续会继续用它改造更多行为。
这一节的核心
这一节把表格的扩展能力继续推进。
关键变化是:
- 单选、多选成为表格基础状态;
- 列配置也进入钩子变量体系;
- 查询表单显示由配置控制;
- 行点击和双击改成事件钩子;
- 双击编辑从统一 handler 转为模块监听;
- 行组件只负责派发事件,不负责决定业务行为。
这让后续表单编辑、父子表联动、批量操作都能建立在更灵活的事件体系上。