19 KiB
19 KiB
列配置系统
**本文引用的文件** - [FmsTable.vue](file://fms-vue/src/components/fms-table/FmsTable.vue) - [createCellRenderer.js](file://fms-vue/src/components/fms-table/utils/createCellRenderer.js) - [createSelectionCellRenderers.js](file://fms-vue/src/components/fms-table/utils/createSelectionCellRenderers.js) - [createEditableCellRenderer.js](file://fms-vue/src/components/fms-table/utils/createEditableCellRenderer.js) - [ModuleListConfigPanel.vue](file://fms-vue/src/views/system/module-management/components/ModuleListConfigPanel.vue)目录
简介
本技术文档聚焦 FMS 表格的列配置系统,系统性说明 displayColumns 的计算逻辑、自定义单元格解析 resolveCustomCell、序号列 seqConfig、列拖拽 columnDraggable 等关键机制;并详解各类列(普通列、选择列、操作列、序号列)的配置方式、显示控制(headerAlign、resizable、showOverflow)、数据绑定(dataIndex、customCell)以及复杂场景(嵌套组件、动态列、条件渲染)的实践方法。
项目结构
FMS 表格由一个容器组件与若干工具模块组成:
- 容器组件:封装 stk-table,负责列装配、编辑态管理、滚动优化、事件转发等。
- 工具模块:
- createCellRenderer:根据列配置生成 customCell(操作列、可编辑列)。
- createSelectionCellRenderers:创建选择列(含全选/单选状态、禁用行支持)。
- createEditableCellRenderer:实现输入框、下拉、复选框等编辑器渲染与值提交。
- 使用示例:在业务页面中通过 columns 定义列,结合 FmsTable 的 props 完成交互。
graph TB
A["FmsTable.vue"] --> B["utils/createCellRenderer.js"]
A --> C["utils/createSelectionCellRenderers.js"]
A --> D["utils/createEditableCellRenderer.js"]
E["业务页面<br/>ModuleListConfigPanel.vue"] --> A
图表来源
- FmsTable.vue:1-828
- createCellRenderer.js:1-229
- createSelectionCellRenderers.js:1-135
- createEditableCellRenderer.js:1-212
- ModuleListConfigPanel.vue:114-163
章节来源
核心组件
- FmsTable.vue:对外暴露 columns、dataSource、rowKey、editable、seq、columnDraggable、rowDraggable、rowSelection、showOverflow 等属性;内部计算 displayColumns,注入选择列、序号列、拖拽列,统一处理 headerAlign、列宽回写、虚拟滚动与编辑激活。
- createCellRenderer.js:resolveCustomCell 将 actions/editor/customCell 转换为最终渲染函数;actions 支持“更多”菜单与确认弹窗;editor 支持 input/select/checkbox。
- createSelectionCellRenderers.js:createSelectionColumn 返回选择列定义,包含表头全选与行级复选框,支持 isRowDisabled 与 onChange。
- createEditableCellRenderer.js:createEditableCell 根据 editor.type 渲染对应控件,维护草稿值、焦点、失焦提交、键盘行为等。
章节来源
- FmsTable.vue:10-37
- createCellRenderer.js:208-228
- createSelectionCellRenderers.js:18-128
- createEditableCellRenderer.js:195-211
架构总览
下图展示列装配与渲染的关键流程:父组件传入 columns → FmsTable 计算 displayColumns → 注入选择列/序号列/拖拽列 → 为每列解析 customCell → 传递给底层表格渲染。
sequenceDiagram
participant P as "父组件"
participant T as "FmsTable.vue"
participant R as "createCellRenderer.js"
participant S as "createSelectionCellRenderers.js"
participant E as "createEditableCellRenderer.js"
participant U as "stk-table"
P->>T : 传入 columns / dataSource / props
T->>T : 计算 seqConfig / columnDragConfig
T->>R : resolveCustomCell(每列)
R-->>T : 返回带 customCell 的列
T->>S : createSelectionColumn()
S-->>T : 返回选择列对象
T->>T : 插入选择列/序号列/拖拽列
T->>U : 传递 displayColumns / data-source / show-overflow
U-->>P : 渲染结果与事件回调
图表来源
- FmsTable.vue:222-291
- createCellRenderer.js:208-228
- createSelectionCellRenderers.js:18-128
- createEditableCellRenderer.js:195-211
详细组件分析
displayColumns 计算逻辑
displayColumns 是列装配的核心,步骤如下:
- 对每列调用 resolveCustomCell,将 actions/editor 转换为 customCell,减少非编辑态下的组件开销。
- 若启用序号列(seq),在最前插入 type=seq 的列,宽度默认 50,不可调整宽度。
- 若启用行拖拽(rowDraggable),在最前插入 dragRow 列。
- 若存在 rowSelection,在最前插入选择列。
- 为所有列统一设置 headerAlign(对齐方式),默认左对齐,选择列/操作列/复选框列居中。
flowchart TD
Start(["开始"]) --> MapCells["遍历 columns<br/>调用 resolveCustomCell"]
MapCells --> CheckSeq{"seq.enabled ?"}
CheckSeq -- 是 --> InsertSeq["插入序号列<br/>type='seq'"]
CheckSeq -- 否 --> Next1["继续"]
InsertSeq --> Next1
Next1 --> CheckDrag{"rowDraggable ?"}
CheckDrag -- 是 --> InsertDrag["插入拖拽列<br/>type='dragRow'"]
CheckDrag -- 否 --> Next2["继续"]
InsertDrag --> Next2
Next2 --> CheckSel{"rowSelection ?"}
CheckSel -- 是 --> InsertSel["插入选择列"]
CheckSel -- 否 --> Next3["继续"]
InsertSel --> Next3
Next3 --> Align["为每列设置 headerAlign"]
Align --> End(["返回 displayColumns"])
图表来源
章节来源
resolveCustomCell 自定义单元格解析
- 若列已提供 customCell,直接返回,不覆盖。
- 若列有 editor:
- 当存在活动编辑行或 editor 类型为 checkbox/select 时,注入 createEditableCell,使该列进入可编辑模式。
- 非编辑态且无 actions 的列,不注入 customCell,走原生 td 渲染路径以提升性能。
- 若列有 actions:
- 生成操作列渲染函数,支持按钮、图标、“更多”下拉菜单、确认弹窗(danger 类型默认)。
- 支持 visible/disabled/onClick 等按行计算的状态。
flowchart TD
In(["进入 resolveCustomCell"]) --> HasCustom{"col.customCell ?"}
HasCustom -- 是 --> ReturnCol["直接返回 col"]
HasCustom -- 否 --> HasEditor{"col.editor ?"}
HasEditor -- 是 --> EditableCheck{"editingActive 或 editor 为 checkbox/select ?"}
EditableCheck -- 是 --> InjectEdit["注入 createEditableCell"]
EditableCheck -- 否 --> NoInject["不注入 customCell"]
HasEditor -- 否 --> HasActions{"col.actions ?"}
HasActions -- 是 --> InjectAction["注入 createActionsCell"]
HasActions -- 否 --> ReturnCol
InjectEdit --> ReturnCol
InjectAction --> ReturnCol
NoInject --> ReturnCol
图表来源
章节来源
seqConfig 序号列配置
- 通过 props.seq 控制:
- true:启用默认序号列,标题“序号”,宽度 50。
- false:关闭序号列。
- 对象:自定义 title 与 width。
- 序号列固定插入到最前列,不可调整宽度(resizable=false),不参与列拖拽。
章节来源
columnDraggable 列拖拽配置
- 通过 props.columnDraggable 控制:
- true:启用列头拖拽,默认允许所有列。
- false:禁用列头拖拽。
- 对象:可配置 disabled 函数或布尔值,用于限制特定列不可拖拽。
- 内置规则:选择列、序号列、拖拽列、展开列、空 dataIndex 列、actions 列禁止拖拽。
章节来源
列类型与配置选项
- 普通列:
- dataIndex:字段映射键。
- title:列标题。
- width:列宽。
- align/headerAlign:内容/表头对齐。
- resizable:是否可调整宽度(由底层库控制)。
- showOverflow:文本溢出处理(由表格整体 showOverflow 控制)。
- 选择列:
- 由 createSelectionColumn 自动生成,包含表头全选与行复选框。
- 支持 getDataSource/getRowKey/getSelectedRowKeys/isRowDisabled/onChange。
- 操作列:
- actions:数组,每项支持 icon/label/type/danger/visible/disabled/confirm/onClick。
- 支持“更多”菜单项与确认弹窗。
- 序号列:
- 由 seq 自动注入,type=seq,不可调整宽度。
- 可编辑列:
- editor:{ type:'input'|'select'|'checkbox', options?, allowClear?, emptyValue?, disabled? }。
- 支持输入框、下拉、复选框三种编辑器。
章节来源
- createSelectionCellRenderers.js:18-128
- createCellRenderer.js:17-206
- createEditableCellRenderer.js:51-148
- createEditableCellRenderer.js:150-193
显示控制机制
- headerAlign:
- 选择列、actions 列、checkbox 列、editor 为 checkbox 的列默认居中对齐。
- 其他列默认左对齐。
- resizable:
- 由底层表格控制;序号列强制不可调整宽度。
- showOverflow:
- 由 FmsTable 的 showOverflow prop 透传给底层表格,控制文本溢出省略。
- 样式层在非选中状态下允许文本选择,避免与库的拖选冲突。
章节来源
列与数据的绑定关系
- dataIndex:
- 作为列与行数据的映射键,用于读取/写入值。
- 编辑器的值变更会写回 row[dataIndex],并通过 change 事件通知父组件。
- customCell:
- 用于自定义渲染,如操作列、选择列、序号列等。
- 若未提供,则根据 editor/actions 自动注入。
- 选择列:
- 通过 selectedRowKeys 与 onChange 同步选中状态。
- 支持行禁用(isRowDisabled)。
章节来源
- createEditableCellRenderer.js:66-70
- createSelectionCellRenderers.js:26-56
- createCellRenderer.js:208-228
依赖关系分析
- FmsTable.vue 依赖:
- createCellRenderer.js:解析 customCell(actions/editor)。
- createSelectionCellRenderers.js:生成选择列。
- createEditableCellRenderer.js:生成编辑器渲染。
- stk-table:底层表格渲染与虚拟滚动。
- 工具模块之间:
- createCellRenderer.js 依赖 createEditableCellRenderer.js。
- createSelectionCellRenderers.js 独立,仅依赖 Vue 响应式能力。
graph LR
F["FmsTable.vue"] --> CR["createCellRenderer.js"]
F --> CS["createSelectionCellRenderers.js"]
F --> CE["createEditableCellRenderer.js"]
CR --> CE
图表来源
- FmsTable.vue:1-828
- createCellRenderer.js:1-229
- createSelectionCellRenderers.js:1-135
- createEditableCellRenderer.js:1-212
章节来源
性能考量
- 虚拟滚动:
- 行数超过阈值时启用虚拟滚动,减少 DOM 节点数量。
- 尺寸变化防抖合并 ResizeObserver 通知,避免频繁重排。
- 编辑态优化:
- 非编辑态下尽量走原生 td 渲染路径,减少函数式组件实例。
- 键盘导航期间延迟激活编辑器,合并连续按键,避免频繁挂载/卸载。
- 选择列:
- 使用原生 input[type=checkbox],零组件开销,提升滚动性能。
- 文本选择:
- 非拖选状态下允许文本选择,避免与库的 user-select:none 冲突。
章节来源
- FmsTable.vue:41-47
- FmsTable.vue:70-96
- FmsTable.vue:103-106
- FmsTable.vue:384-448
- createSelectionCellRenderers.js:58-85
- FmsTable.vue:750-767
故障排查指南
- 列未显示:
- 检查 columns 是否正确传入,dataIndex 是否与数据一致。
- 确认 seq/columnDraggable/rowSelection 是否意外插入了隐藏列。
- 操作列点击无效:
- 检查 action.disabled/visible 是否按行返回了预期状态。
- 确认 onClick 是否被阻止冒泡(stopPropagation 已内置)。
- 编辑器值未提交:
- 检查 shouldNotify 逻辑,确保值确实发生变化。
- 确认 blur/回车/esc 行为是否符合预期。
- 文本溢出异常:
- 确认 showOverflow 是否开启,样式层是否应用了省略规则。
- 选择列状态不同步:
- 检查 getSelectedRowKeys 是否返回最新选中键集合。
- 确认 onChange 是否更新父组件 state。
章节来源
- createCellRenderer.js:13-15
- createCellRenderer.js:121-128
- createEditableCellRenderer.js:66-70
- createEditableCellRenderer.js:107-126
- createSelectionCellRenderers.js:26-56
- FmsTable.vue:750-767
结论
FMS 表格的列配置系统以 FmsTable.vue 为核心,通过 displayColumns 计算与 resolveCustomCell 解析,实现了高度可扩展的列体系。其设计兼顾易用性与性能:默认注入选择列/序号列/拖拽列,按需注入编辑器与操作列,非编辑态最小化组件开销;同时提供丰富的显示控制与数据绑定能力,满足复杂业务场景需求。
附录:实战示例与最佳实践
- 普通列与可编辑列:
- 使用 dataIndex 绑定字段,editor 配置输入框/下拉/复选框。
- 参考:ModuleListConfigPanel.vue:114-136
- 操作列:
- 配置 actions 数组,支持图标、标签、危险样式、“更多”菜单与确认弹窗。
- 参考:createCellRenderer.js:17-206
- 选择列:
- 通过 rowSelection 启用,自动注入选择列,支持全选与行禁用。
- 参考:createSelectionCellRenderers.js:18-128
- 动态列生成:
- 根据字段元数据或用户配置动态构建 columns,再传入 FmsTable。
- 参考:ModuleListConfigPanel.vue:114-136
- 条件渲染:
- 使用 action.visible/disabled 或 editor.disabled 按行控制可见性与可用性。
- 参考:createCellRenderer.js:9-15
- 参考:createEditableCellRenderer.js:72-76
- 复杂列配置:
- 组合使用 customCell、editor、actions,实现嵌套组件与高级交互。
- 参考:createCellRenderer.js:208-228
- 参考:createEditableCellRenderer.js:195-211
章节来源