Appearance
FinEditableTable 可编辑表格
组件与命名规范:组件名主推
FEditableTable,别名导出FinEditableTable。
基于 el-table + FinForm 验证体系构建的行级可编辑表格组件。支持增删改、撤回、快捷键、编辑/查看模式切换、自定义插槽等完整功能。
基础用法
最简单的用法:通过 tableConfig.columns 配置列,通过 v-model:data 传入草稿数据。公共表格能力与编辑配置统一放在 tableConfig 中;searchFormConfig、searchPanelConfig、crudConfig 不适用于编辑表格。
loading
配置入口
组件仅保留两个顶层入口:tableConfig 和 v-model:data。普通表格的标题、列、复选、单选、序号、工具栏、行操作、分页、请求、树形、展开、虚拟滚动及原生表格属性均放入 tableConfig;编辑模式、失焦保存、插入位置、撤销、快捷键和新行默认值也放入同一容器。
旧属性迁移关系:showSelection 改为 tableConfig.selection;showActionColumn、actionColumnWidth、actionColumnFixed、rowActions 合并为 tableConfig.rowActionConfig;tableSize 改为 tableConfig.size;其余编辑属性直接移入 tableConfig。不保留两套并行入口。
静态分页时 data 表示完整草稿,组件只对展示数据切片;远程分页时 data 表示当前服务端页草稿。翻页、修改页大小及远程刷新前会先校验并本地保存全部编辑行,失败时保留原页和草稿,不调用业务提交接口。
vue
<FEditableTable
v-model:data="rows"
:table-config="{
columns,
selection: true,
index: { continuous: true },
pagination: { pageSize: 20 },
rowActionConfig: { width: 180, showEdit: true, showDelete: true },
mode: 'edit',
autoSaveOnBlur: true,
}"
/>公共表格配置演示
下面三个实例使用相同的公共列类型,通过稳定的 EditableTableConfig 配置对象分别演示静态分页与列设置、数字行键树形默认展开、虚拟列表编辑。编辑控件统一写在列的 formItem 中。
行内按钮需要显式配置 rowActionConfig;不配置时仍可点击单元格进入编辑,并使用失焦保存或快捷键保存。关闭分页使用 pagination: false,避免小数据示例显示不必要的分页区域。
loading
插入位置
通过 tableConfig.insertPosition 配置普通新增的方向:top 为上方,bottom 为下方,默认下方。有选中行时插入选中行上方或下方,没有选中行时插入表格顶部或底部。“上一行/下一行”按钮覆盖本次插入方向,不修改全局配置。兼容 beforeSelected、afterSelected,分别按上方、下方处理。多选时以选中记录中的第一条有效行为参照。
loading
工具栏配置
使用与普通表格一致的 toolbarConfig,不再使用 showToolbar。enabled 默认开启,actions 配置按钮列表,maxCount、morePosition、showDivider 沿用公共按钮组规则。
默认仅提供一个新增按钮;上一行、下一行必须显式配置。普通新增键 add 遵循全局 insertPosition,固定动作键 insertBefore/top 表示本次插上方,insertAfter/bottom 表示本次插下方。有参照行时相对插入,没有参照行时插表首或表尾。
ts
toolbarConfig: {
enabled: true,
maxCount: 3,
actions: [
{ key: 'add', label: '新增', type: 'primary' },
{ key: 'insertBefore', label: '上一行' },
{ key: 'insertAfter', label: '下一行' },
],
}关闭工具栏使用 tableConfig.toolbarConfig: { enabled: false },显式传入 actions: [] 不生成默认新增按钮。自定义按钮继续使用公共按钮的外观、显隐、禁用、确认及点击回调配置;回调参数中的 rows 为当前勾选记录。列设置复用普通表格的列显隐、排序、宽度及本地存储能力;切换列结构前同样经过编辑保存门禁。
查看模式 vs 编辑模式
通过 tableConfig.mode 切换 'edit' 和 'view'。查看模式下单元格只读;配置 rowActionConfig 后仍可通过行内编辑按钮返回编辑模式。
loading
表单验证
列定义中配置 rules 即可启用验证,使用与表单相同的规则适配及标准校验引擎。支持必填简写、类型、正则、长度、范围、枚举、回调校验和返回承诺的校验;asyncValidator(value, row) 返回错误字符串或空值。保存时执行全部规则,不根据触发时机跳过规则。
工具栏新增、上一行、下一行以及头部插槽提供的 addRow(position?) 会先保存校验当前编辑行,失败时保留原行与下方错误提示,不创建新行。复选框勾选行优先于高亮当前行,插入参照在校验前固定。实例暴露的 addRow、insertRow 保持同步底层数据操作,不执行交互校验;自定义新增按钮应使用头部插槽的 addRow。
保存只代表组件提交本地数据,不会等待业务接口;字段编辑在保存时同步外部数据,新增、删除和撤销立即同步。切换查看模式前会等待编辑行保存,失败则保留编辑模式;调用 enterViewMode() 应等待异步布尔结果。
选择控件
选择列可使用 component: 'select' 或 component: 'FSelect'。选项沿用表单的标签、值、禁用结构,支持静态数组和异步加载函数。新配置显式提供 formItem.options 时覆盖旧控件属性中的选项;新配置内部仍以 formItem.componentProps.options 优先。未提供新选项配置时,兼容控件属性中的选项、列选项、枚举的原有优先级。展示态优先插槽、渲染和格式化,再映射选项标签。
loading
loading
自定义列模板
通过 slot 属性指定插槽名实现自定义渲染,通过 render 函数实现纯视图自定义,通过 component 指定编辑组件。
loading
自定义插槽
支持 #header-left、#header-right、#footer 三个容器插槽,以及列级 #cell-{slot} 插槽。
loading
完整功能展示
所有功能在同一页中使用:多选行、Ctrl+S 保存、Ctrl+Z 撤回、点击行编辑、失焦保存、表单验证。
loading
原生表格属性
组件属性继承底层表格的 TableProps,可直接配置 showHeader、showSummary、summaryMethod、rowClassName、cellStyle、tableLayout 等,原生属性传给内部表格,不落到外层容器。容器的类名、样式和自定义标识仍留在外层。
data 由编辑表格内部维护;rowKey 沿用公共表格的原生类型,支持字符串字段名或返回字符串的函数,字段值可以是数字。函数行键无法为新行解析有效键时,必须由新行数据或 newRowDefaults 提供可解析值。边框、斑马纹和当前行高亮默认开启,高亮可通过 highlightCurrentRow: false 关闭。其他未配置的原生属性沿用底层默认值。
原生非冲突事件可直接监听,例如 sort-change、current-change 和 cell-click,内部编辑与选择逻辑仍会执行。selection-change 保持原业务事件;row-click 保持原有 (row, index) 编辑入口事件,不等同于底层的 (row, column, event)。本次不扩展原生实例方法和插槽,加载指令也不属于表格属性。
loading
快捷键
| 快捷键 | 功能 | 是否可配置 |
|---|---|---|
Ctrl+S / Cmd+S | 保存当前编辑行 | tableConfig.enableCtrlS |
Ctrl+Z / Cmd+Z | 撤回上一步操作 | tableConfig.enableCtrlZ |
Esc | 取消当前编辑行 | 始终启用(有编辑行时) |
| 点击行 | 进入编辑模式 | — |
| 失焦 | 自动保存 | tableConfig.autoSaveOnBlur |
API
Props
组件只声明 tableConfig 与 v-model:data 两个顶层属性。tableConfig 类型为 EditableTableConfig,直接继承公共 TableConfig,仅排除 data、searchFormConfig、searchPanelConfig、crudConfig;columns 直接沿用 TableConfig['columns'],EditableTableColumn 只是公共 TableColumnConfig 的别名,不是另一套列类型。编辑专属配置及默认值见下表:
| 配置 | 默认值 |
|---|---|
mode | 'edit' |
singleEdit | true |
autoSaveOnBlur | true |
insertPosition | 'bottom' |
undoable / enableCtrlS / enableCtrlZ | true |
maxUndoStack | 50 |
deletable / addable | true |
newRowDefaults | — |
EditableTableColumn
与普通表格共用基础列配置和展示格式化能力;行内编辑通过 formItem 复用表单字段配置及组件注册表,保留旧版顶层字段写法。支持的属性如下:
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
field | 字段名(必填) | string | — |
label | 列标题 | string | — |
editable | 是否可编辑 | boolean | true |
render | 自定义视图渲染函数 | (row, index) => any | — |
width | 列宽 | number | string | — |
minWidth | 最小列宽 | number | string | — |
align | 对齐方式 | 'left' | 'center' | 'right' | 'left' |
headerAlign | 表头对齐方式 | 'left' | 'center' | 'right' | 'left' |
fixed | 固定列 | 'left' | 'right' | boolean | — |
showOverflowTooltip | 溢出时显示 tooltip | boolean | true |
slot | 插槽名称,通过 #cell-{slot} 使用 | string | — |
visible | 是否显示 | boolean | true |
推荐使用
formItem配置编辑字段。同名配置以formItem为准,未配置项兼容顶层component、componentProps、required、rules、options、defaultValue,其中旧版default作为默认值兜底。字段名始终取列的field。表单注册的控件无需再次注册,即可用于行内编辑。
componentProps和dynamicDisabled回调读取当前行上下文,model为当前行,schemas仅包含当前字段。支持读取和设置行字段,不支持完整表单布局、表单级联动或修改整表配置;重置请使用表格取消编辑接口。展示优先级为:实际存在的插槽、自定义
render、旧版formatCell、公共formatter、选项/枚举标签、原值。插槽按cell-插槽名、显式插槽名、col-字段名、字段名依次查找,提供row、value、index、column。
ts
const columns = [
{
field: 'amount',
label: '金额',
formatter: 'money',
formItem: {
component: 'FInputNumber',
required: '请输入金额',
defaultValue: 0,
componentProps: { min: 0, precision: 2 },
},
},
]| 配置 | 说明 |
|---|---|
options | 静态选项数组或返回选项数组的异步函数 |
rules | 标准规则数组,支持回调和异步校验 |
required | 布尔值或自定义必填错误文案 |
formatCell | 展示值格式化函数 |
enum | 兼容枚举数组或值到标签的映射 |
emptyText | 空值展示文案 |
Events
| 事件 | 说明 | 参数 |
|---|---|---|
update:data | 数据变更 | data: Record<string, any>[] |
update:mode | 模式变更 | mode: 'edit' | 'view' |
row-add | 新增行 | (row, index) |
row-delete | 删除行 | (row, index) |
row-edit | 进入编辑 | (row, index) |
row-save | 保存行 | (row, index) |
row-cancel | 取消编辑 | (row, index) |
row-click | 点击行 | (row, index) |
cell-change | 单元格值变更 | (row, field, value) |
undo | 执行撤回 | (action: UndoAction) |
selection-change | 选择行变更 | (rows) |
Slots
| 插槽 | 说明 | 作用域 |
|---|---|---|
header-left | 工具栏左侧区域 | { canUndo, mode, addRow },addRow(position?) 可覆盖本次插入方向 |
header-right | 工具栏右侧区域 | { mode } |
footer | 表格底部区域 | { data, mode } |
cell-{slot} | 列级自定义插槽 | { row, value } |
Exposed Methods
通过 ref 调用组件暴露的方法:
ts
const tableRef = ref<InstanceType<typeof FinEditableTable>>()
// 数据操作
tableRef.value.getData() // 获取全部数据
tableRef.value.getRow(rowKey) // 获取单行
tableRef.value.setData(newData) // 替换全部数据
tableRef.value.setValues({ name: '新名' }) // 批量更新
// 行 CRUD
tableRef.value.addRow() // 新增行(使用 insertPosition)
tableRef.value.addRow({ name: '预填' }) // 新增带默认值
tableRef.value.deleteRow(rowKey) // 删除行
tableRef.value.insertRow(row, position, refKey) // 指定位置插入
// 编辑操作
tableRef.value.editRow(rowKey) // 进入编辑
tableRef.value.saveRow(rowKey) // 保存(含验证)
tableRef.value.cancelRow(rowKey) // 取消编辑(回退)
tableRef.value.isEditing(rowKey) // 是否编辑中
tableRef.value.enterEditMode() // 切换到编辑模式
await tableRef.value.enterViewMode() // 保存成功才切换,返回是否成功
// 验证
await tableRef.value.validate() // 验证全部
await tableRef.value.validateRow(rowKey) // 验证单行
// 撤回
tableRef.value.undo() // 撤回上一步
tableRef.value.canUndo() // 是否可撤回
tableRef.value.clearUndoStack() // 清空撤回栈
// 选择
tableRef.value.getSelectionRows() // 获取选中行
tableRef.value.refresh() // 强制刷新