@minnee/pro-arco-table
v1.1.12
Published
Enhanced Table component based on Arco Design with extended column types
Downloads
82
Maintainers
Readme
Pro Arco Table
基于 Arco Design Vue 封装的增强型表格组件,提供搜索表单、工具栏、远程/本地数据请求、分页、滚动、可编辑单元格/行、类型安全的渲染与事件等能力。
安装与依赖
- 运行环境:Vue 3.5+、TypeScript 5+
- 对等依赖:@arco-design/web-vue、vue(请在宿主项目中安装)
npm i @minnee/pro-arco-table
# 对等依赖(如未安装)
npm i vue @arco-design/web-vue快速使用
- 具名导出(仅支持具名导出):
import { ProArcoTable } from '@minnee/pro-arco-table'- 在示例项目/本地开发:
import { ProArcoTable } from '../../src/index'- 全局注册(可选):
import { createApp } from 'vue'
import ArcoVue from '@arco-design/web-vue'
import { install as installProArcoTable } from '@minnee/pro-arco-table'
const app = createApp(App)
app.use(ArcoVue)
installProArcoTable(app)
app.mount('#app')- 样式
从 v1.1.3 起,库构建改为“产出独立 CSS 文件”。宿主项目需要显式引入库样式:
// main.ts 或组件入口 import '@minnee/pro-arco-table/dist/style.css' // 同时确保引入 Arco 基础样式(示例): import '@arco-design/web-vue/es/index.css'这样可避免生产环境下 CSP/时序导致的样式注入失败问题。
主要能力(概览)
- 内置搜索表单与工具栏,统一参数管理与触发请求
- 远程/本地模式:支持请求方法驱动的远程数据与本地静态数据
- 分页、滚动与数据总数联动(远程模式自动同步 total)
- 渲染类型与自定义渲染(依赖类型定义,安全约束)
- 行/单元格编辑模式(含保存/取消、校验、只读占位实现)
- 错误/空状态渲染与统一的请求状态回调
更多实现细节可参考:
- 入口与导出:
src/index.ts - 主组件:
src/table.vue - 类型定义:
src/types/index.ts、src/types/editable.ts - 常用工具:
src/utils/tools.ts
工程化配置
- 构建:
vite.config.mts(库模式,ESM/UMD 双产物;UMD 使用具名导出策略;独立 CSS 输出为dist/style.css) - 代码规范:
eslint.config.js(Flat Config,TypeScript + Vue 规则) - 类型:
tsconfig.json(strict/无多余 emit,配合 vite-plugin-dts 生成类型声明) - 提交钩子:
.husky/pre-commit(lint-staged 自动修复)
开发与构建
# 本地开发(示例在 examples/ 下)
npm run dev
# 类型检查
npm run type-check
# 代码规范检查与自动修复
npm run lint
# 单元测试
npm test
# 构建库
npm run build使用建议
- 仅具名导出:请使用
import { ProArcoTable } from '@minnee/pro-arco-table' - UMD 使用(浏览器全局):库名为
ArcoTableEnhanced,成员以具名属性暴露(例如window.ArcoTableEnhanced.ProArcoTable) - 详细的 Props/事件/类型请参考源码中的 TSDoc 注释与类型定义文件
API 文档
表格配置(ProArcoTableProps)
| 参数 | 说明 | 类型 | 默认值 | |------|------|------|--------| | data | 本地数据(与 requestMethod 互斥) | T[] | - | | requestMethod | 远程数据请求方法(与 data 互斥) | (params?: SearchParams, extra?: { signal?: AbortSignal }) => Promise<RequestResponse> | - | | rowKey | 行主键字段 | string | 'id' | | columns | 扩展的列配置集合 | ProArcoColumnData[] | - | | requestParams | 额外的请求参数,会与分页/搜索参数合并 | SearchParams | - | | paginationFieldNames | 分页字段映射:将内部 current/pageSize 映射为后端要求的字段名(例如 page/limit);若同时配置 beforeRequest,会先执行 beforeRequest 转换再进行字段映射 | PaginationFieldNames | - | | beforeRequest | 请求前转换请求参数(返回新参数) | (params: SearchParams) => SearchParams | - | | afterRequest | 请求后转换请求结果(返回 { data, total }) | (resp: unknown) => RequestResponse | - | | polling | 轮询间隔(毫秒);0/undefined 表示不开启 | number | - | | autoRequest | 参数变化时自动请求数据 | boolean | true | | onMountedRequest | 组件挂载后是否立即请求数据 | boolean | true | | scroll | 表格的滚动属性配置,与 a-table 的 scroll 属性一致 | { x?: number | string; y?: number | string; minWidth?: number | string; maxHeight?: number | string; } | - | | toolbarConfig | 工具栏配置:true/undefined 使用默认配置;false 不显示;对象为合并后的配置 | ToolbarConfig | boolean | { add: false, download: false } | | searchConfig | 查询表单配置:true/undefined 使用默认配置;false 不显示;对象为合并后的配置 | SearchConfig | boolean | { show: true, layout: 'inline', span: 4, searchText: '查询', resetText: '重置', showExpandButton: true, divider: true, resetConfig: { keepSearchParams: true } } | | errorRenderer | 自定义错误渲染(优先级高于默认错误呈现) | (ctx: { error: unknown }) => VNodeChild | null | - | | emptyRenderer | 自定义空状态渲染 | () => VNodeChild | null | - | | autoHeightConfig | 自适应高度配置:true/undefined 使用默认配置;false 关闭自适应;对象为合并后的配置 | AutoHeightConfig | boolean | { getScrollContainer: undefined, minHeight: 240, extraOffset: 0 } | | onRequestStateChange | 请求生命周期回调:loading/success/error | RequestStateCallback | - |
列配置(ProArcoColumnData)
| 参数 | 说明 | 类型 | 默认值 | |------|------|------|--------| | title | 列头显示的标题(必填) | string | RenderFunction | - | | dataIndex | 列对应的数据字段(必填) | string | - | | downloadIndex | 下载使用的列索引,优先于 dataIndex | string | dataIndex | | valueType | 值类型,驱动渲染与搜索/编辑控件类型 | ValueType | undefined ('input' 为默认) | 'input' | | valueEnum | 枚举映射(仅 valueType=select 生效) | ValueEnum | - | | search | 列级搜索配置:false 关闭;true 等价 {};对象时类型随 valueType 收敛 | boolean | SearchConfigFor | - | | editable | 列级编辑配置:false 关闭;true 使用默认;对象支持 editValueType 精确约束 fieldProps | boolean | EditableConfigFor | - | | copyable | 是否支持双击复制单元格内容,若启用单元格编辑且双击的单元格可编辑,则优先触发编辑 | boolean | false | | copyText | 自定义复制文本(优先于单元格显示文本) | string | - | | show | 是否在表格中显示该列;为 false 时隐藏,但不影响查询表头渲染 | boolean | true |
ValueType 与 FieldProps 映射
| ValueType | 说明 | 对应组件属性类型 | |-----------|---------|-------------------| | input | 输入框 | InputProps | | textarea | 多行输入 | TextAreaProps | | number | 数字输入 | InputNumberProps | | select | 下拉选择(支持 valueEnum) | SelectProps | | radio | 单选组(支持 valueEnum) | RadioGroupProps | | cascader | 级联选择 | CascaderProps | | date | 日期选择 | PickerProps | | week | 周选择 | WeekPickerProps & CommonPickerProps | | month | 月份选择 | MonthPickerProps & CommonPickerProps | | quarter | 季度选择 | QuarterPickerProps & CommonPickerProps | | year | 年份选择 | YearPickerProps & CommonPickerProps | | dateTime | 日期时间选择 | PickerProps | | time | 时间选择 | TimePickerProps | | dateRange | 日期范围选择 | RangePickerProps | | dateTimeRange | 日期时间范围选择 | RangePickerProps | | timeRange | 时间范围选择 | TimePickerProps |
查询表单配置(SearchConfig)
| 参数 | 说明 | 类型 | 默认值 | |------|------|------|--------| | show | 是否显示查询表单 | boolean | true | | layout | 表单布局 | 'horizontal' | 'vertical' | 'inline' | 'inline' | | span | 每行显示的表单项数量 | number | 4 | | searchText | 查询按钮文本 | string | '查询' | | resetText | 重置按钮文本 | string | '重置' | | showExpandButton | 是否显示展开按钮(false 时不会折叠) | boolean | true | | wrapperStyle | 查询表单最外层容器的样式 | CSSProperties | - | | divider | 是否在搜索表单下方显示分割线 | boolean | true | | resetConfig | 重置行为:当 keepSearchParams=true 时,重置后回填父层提供的初始搜索参数(:search-params),不保留交互过程中表单内部值;重置不影响 requestParams | { keepSearchParams?: boolean } | { keepSearchParams: true } |
列级搜索(column.search)
- 搜索对象类型:boolean | SearchConfigFor
- false:关闭该列的搜索能力
- true:启用默认搜索配置(等价于 {})
- 对象:根据列的 valueType 收敛具体字段类型
- searchIndex:自定义该搜索项的表单字段名;未设置时回退到列的 dataIndex;提交参数以该字段为键
- 注意:请求参数的转换仅通过 props.beforeRequest 统一处理;列级不再支持 transform;子组件会把原始表单值透传,最终由父组件请求管线转换
列级 fieldSlots(搜索输入插槽)
- 作用:在不改动组件整体的情况下,对输入组件的局部区域进行定制(例如 Input 的前后缀、Select 的下拉项/空态/页眉页脚、Date/Time 选择器的图标/额外内容等)。
- 配置位置:列的 search.fieldSlots,类型会依据列的 valueType 精确约束。
- 实现说明:由于 Vue 3 模板不支持对象式
v-slots的直接传递,本库通过遍历fieldSlots并使用v-slot:[name]动态生成具名插槽,同时提供通用SlotRenderer以支持函数式插槽渲染上下文。 - 类型映射(节选,详见
src/types/index.ts中的定义):- InputSlots:prefix/suffix/prepend/append,插槽参数为
{ fieldProps } - InputNumberSlots:minus/plus/prefix/suffix,插槽参数为
{ fieldProps } - SelectSlots:extra/header/footer/prefix/option/label/empty/search-icon/arrow-icon,插槽参数随具体插槽而定(例如
option/label为{ option }) - CascaderSlots:prefix/label/option/empty/search-icon/loading-icon/arrow-icon,插槽参数随具体插槽而定(例如
label/option为{ data };其他为{ fieldProps }) - DatePickerSlots:prefix/suffix-icon/extra/cell,插槽参数分别为
{ fieldProps }、{ fieldProps }、{ fieldProps }、{ value, date, isCurrentMonth } - TimePickerSlots:prefix/suffix-icon/extra,插槽参数为
{ fieldProps }
- InputSlots:prefix/suffix/prepend/append,插槽参数为
- 使用示例(简要):
columns: [
{
title: '名称',
dataIndex: 'name',
valueType: 'input',
search: {
fieldSlots: {
prefix: ({ fieldProps }) => '👤',
suffix: ({ fieldProps }) => '✓',
},
},
},
{
title: '状态',
dataIndex: 'status',
valueType: 'select',
valueEnum: {
0: { label: '未启用' },
1: { label: '启用' },
},
search: {
fieldSlots: {
option: ({ option }) => option.label,
empty: () => '暂无选项',
},
},
},
]- 注意事项:
- 插槽名需与类型映射严格匹配,否则不会生效(静默忽略)。
- 插槽函数的参数签名需与映射一致;IDE 将给出类型提示。
- 区间类组件(dateRange/dateTimeRange/timeRange)当前不提供自定义
cell插槽;可通过外部渲染实现更复杂需求。 - textarea/radio 暂不支持插槽透传。
工具栏配置(ToolbarConfig)
| 参数 | 说明 | 类型 | 默认值 | |------|------|------|--------| | add | 新增按钮配置;false 不显示 | { text?: string; onClick: (e?: Event) => void } | false | | download | 下载按钮配置;false 不显示;undefined 使用默认配置 | DownloadConfig | false | undefined | false |
下载配置(DownloadConfig)
| 参数 | 说明 | 类型 | 默认值 | |------|------|------|--------| | fileName | 下载的文件名称 | string | - | | pageSize | 每次请求多少条数据 | number | 200 | | maxRowsPerFile | 单个导出文件的最大行数(不含表头),超出自动分卷 | number | 1000000 | | onProgress | 下载进度回调(仅远程下载实时更新) | (info: { downloaded: number; total: number; percent: number; part: number; page: number; pageSize: number }) => void | - | | throttleMs | 每页请求之间的节流时间(毫秒) | number | - | | retryCount | 请求失败的重试次数(指数退避) | number | 0 | | retryDelayBaseMs | 重试的基础延迟(毫秒);实际延迟为 base * 2^attempt | number | 500 | | afterDownload | 下载完成后的回调 | () => void | - |
返回参数(RequestResponse)
| 参数 | 说明 | 类型 | |------|------|------| | data | 数据列表 | T[] | | total | 总条数 | number |
请求生命周期与转换
| 参数 | 说明 | 类型 | |------|------|------| | beforeRequest | 请求前转换参数(返回新 SearchParams) | (params: SearchParams) => SearchParams | | afterRequest | 请求后转换响应(返回 { data, total }) | (resp: unknown) => RequestResponse | | onRequestStateChange.state | 请求阶段 | 'loading' | 'success' | 'error' | | onRequestStateChange.context.originalParams | 转换前的原始参数 | SearchParams | | onRequestStateChange.context.params | 转换后的最终参数 | SearchParams | | onRequestStateChange.context.response | 标准响应(成功时存在) | RequestResponse | undefined | | onRequestStateChange.context.error | 错误对象(失败时存在) | unknown | | onRequestStateChange.context.fromPolling | 是否来源于轮询 | boolean | undefined |
表格方法(ProArcoTableMethods)
| 方法名 | 说明 | 类型 | |--------|------|------| | fetchData | 手动请求数据;早退场景返回 null | () => Promise<RequestResponse | null> | | reload | 重新拉取数据;resetPage 为 true 时先重置到第一页 | (resetPage?: boolean) => void | | resetAndReload | 清空搜索条件并重置到第一页后拉取 | () => void | | startEditable | 开始编辑(智能路由 行/单元格) | (rowKey: string, columnKey: string, record?: T) => Promise | (rowKey: string | string[], record?: T | T[]) => Promise | | saveEditable | 保存编辑(行/单元格) | (rowKey?: string | string[]) => Promise | (rowKey: string, columnKey: string) => Promise | | cancelEditable | 取消编辑(行/单元格) | (rowKey?: string | string[]) => Promise | (rowKey: string, columnKey: string) => Promise |
编辑配置(EditableConfig)
| 参数 | 说明 | 类型 | 默认值 | |------|------|------|--------| | type | 编辑类型:单元格/行 | 'cell' | 'row' | 'row' | | trigger | 触发方式:外部调用/双击 | 'external' | 'dblclick' | 'external' | | multiple | 多行编辑(仅行编辑有效) | boolean | false | | saveText | 保存按钮文本 | string | '保存' | | cancelText | 取消按钮文本 | string | '取消' | | saveOnBlur | 失焦自动保存(单元格编辑) | boolean | true | | validateOnBlur | 失焦自动校验(行/单元格) | boolean | true | | disableOtherActionsWhenEditing | 编辑时禁用其它操作(分页/筛选/导出等) | boolean | false | | onSave | 保存回调(通过列级 FormItem 校验后触发) | (newRecord: T, oldRecord: T, rowKey: string, rowIndex: number) => void | Promise | - | | onCancel | 取消回调(撤销变更后触发) | (rowKey: string, record: T, rowIndex: number) => void | Promise | - | | onChange | 字段变化回调(仅编辑中) | (rowData: T, field: string, value: unknown, rowKey: string, rowIndex: number) => void | - |
可编辑表格方法(EditableTableMethods)
| 方法名 | 说明 | 类型 | |--------|------|------| | isEditing | 检查是否处于编辑状态(全局/行/单元格) | (rowKey?: string, dataIndex?: string) => boolean | | getRowsData | 获取整表或指定行数据 | (rowKey?: string) => T | T[] | undefined | | setRowData | 设置行数据(浅合并第一层) | (rowKey: string, data: Partial) => void | | validate | 校验指定行或全部编辑中行 | (rowKeys?: string[]) => Promise | | startRowEditable | 开始行编辑(支持多行) | (rowKey: string | string[], record?: T | T[]) => Promise | | saveRowEditable | 保存行编辑(全部或指定行) | (rowKey?: string | string[]) => Promise | | cancelRowEditable | 取消行编辑(全部或指定行) | (rowKey?: string | string[]) => Promise | | startCellEditable | 开始单元格编辑 | (rowKey: string, columnKey: string, record?: T) => Promise | | saveCellEditable | 保存单元格编辑 | (rowKey: string, columnKey: string) => Promise | | cancelCellEditable | 取消单元格编辑 | (rowKey: string, columnKey: string) => Promise | | isRowEditing | 指定行是否处于编辑 | (rowKey?: string) => boolean | | isCellEditing | 指定单元格是否处于编辑 | (rowKey?: string, columnKey?: string) => boolean | | getRowData | 便捷获取单行数据 | (rowKey: string) => T | undefined | | getFieldPath | 生成内部字段路径(rowKey + dataIndex) | (rowKey: string, dataIndex: string) => string |
许可协议
MIT
