BaseTable
如何使用
<BasicTable @register="registerTable">
</BasicTable>
import { BasicTable, useTable } from '@/components/Table';
const [registerTable,methodsObj ]= useTable({
columns:tableColumns
})
树形表格
当isTreeTable为true时,开启树形表格
<BasicTable @register="register">
</BasicTable>
import { BasicTable, useTable } from '@/components/Table';
const [register, { expandAll, collapseAll, expandRows, collapseRows }] = useTable({
isTreeTable: true,
accordion: true, // 手风琴效果
rowSelection: {
type: 'checkbox',
getCheckboxProps(record: Recordable) {
// Demo: 第一行(id为0)的选择框禁用
if (record.id === '0') {
return { disabled: true };
} else {
return { disabled: false };
}
},
},
columns: [
{
title: 'ID',
dataIndex: 'id',
fixed: 'left',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
width: 150,
filters: [
{ text: 'Male', value: 'male' },
{ text: 'Female', value: 'female' },
],
},
{
title: '地址',
dataIndex: 'address',
}
],
dataSource: getTreeTableData(),
rowKey: 'id',
showSelectionBar: true, // 显示多选状态栏
});
远程加载数据
当你的表格需要向后台发送请求获取表格属性 useTable 参数中使用api属性属性值传请求方法,调用reload方法可刷新表格数据,
// 请求之前处理参数
beforeFetch?: Fn;
// 自定义处理接口返回参数
afterFetch?: Fn;
// 查询条件请求之前处理
handleSearchInfoFn?: Fn;
// 请求接口配置
fetchSetting?: Partial<FetchSetting>;
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleReloadCurrent"> 刷新当前页 </a-button>
<a-button type="primary" @click="handleReload"> 刷新并返回第一页 </a-button>
</template>
</BasicTable>
import { BasicTable, useTable } from '@/components/Table';
const [registerTable, { reload }] = useTable({
title: '远程加载示例',
api: demoListApi,
columns: getBasicColumns(),
pagination: { pageSize: 10 },
fetchSetting: {
listField: 'data.list',
totalField: 'data.total',
},
});
function handleReloadCurrent() {
reload();
}
function handleReload() {
reload({ page: 1 });
}
自定义表格内容
用法与antD中用法一致、
<BasicTable @register="registerTable">
<template #bodyCell="{ column, record, text }">
<template v-if="column.key === 'id'"> ID: {{ record.id }} </template>
<template v-else-if="column.key === 'no'">
<Tag color="green">
{{ record.no }}
</Tag>
</template>
<template v-else-if="column.key === 'avatar'">
<Avatar :size="60" :src="record.avatar" />
</template>
<template v-else-if="column.key === 'imgArr'">
<TableImg :size="60" :simpleShow="true" :imgList="text" />
</template>
<template v-else-if="column.key === 'imgs'">
<TableImg :size="60" :imgList="text" />
</template>
<template v-else-if="column.key === 'category'">
<Tag color="green">
{{ record.no }}
</Tag>
</template>
</template>
</BasicTable>
启用Form表单查询表格数据
useTable中的useSearchForm参数设置为true,formConfig中设置表单相关内容,属性与antD中属性一致,详细查看formConfig
<BasicTable @register="registerTable">
<template #form-custom> custom-slot </template>
<template #toolbar>
<a-button type="primary" @click="getFormValues">获取表单数据</a-button>
</template>
</BasicTable>
import { BasicTable, useTable } from '@/components/Table';
const [registerTable, { getForm }] = useTable({
title: '开启搜索区域',
api: demoListApi,
columns: getBasicColumns(),
useSearchForm: true,
formConfig: {
labelWidth: 100,
schemas: [
{
field: 'field0',
label: '字段0',
component: 'Input',
colProps: {
xl: 12,
xxl: 8,
},
},
{
field: `field11`,
label: `Slot示例`,
//自定义表单
slot: 'custom',
colProps: {
xl: 12,
xxl: 8,
},
},
]
},
showTableSetting: true,
tableSetting: { fullScreen: true },
showIndexColumn: false,
rowKey: 'id',
rowSelection: {
type: 'checkbox',
},
showSelectionBar: true, // 显示多选状态栏
});
function getFormValues() {
console.log(getForm().getFieldsValue());
}
可展开表格
expandRowByClick设置为true时,表格可展开,可配置stopButtonPropagation来阻止操作按钮的点击事件冒泡
<BasicTable @register="registerTable">
<template #expandedRowRender="{ record }">
<span>No: {{ record.no }} </span>
</template>
</BasicTable>
const [registerTable] = useTable({
api: demoListApi,
columns: getBasicColumns(),
rowKey: 'id',
canResize: false,
expandRowByClick: true,
accordion: true, // 手风琴效果
actionColumn: {
width: 160,
title: 'Action',
dataIndex: 'action',
fixed: 'right',
// slots: { customRender: 'action' },
},
});
自定义表头
用法与antd中自定义表头用法一致
<BasicTable @register="registerTable">
<template #headerCell="{ column }">
<template v-if="column.key === 'name'">
<span>
姓名
<BasicHelp class="ml-2" text="headerHelpMessage方式2" />
</span>
</template>
<template v-else-if="column.key === 'address'">
地址
<FormOutlined class="ml-2" />
</template>
<template v-else>
<HeaderCell :column="column" />
</template>
</template>
</BasicTable>
const [registerTable] = useTable({
title: '定高/头部自定义',
api: demoListApi,
columns: getCustomHeaderColumns(),
canResize: false,
scroll: { y: 100 },
});
表位合计行
<BasicTable @register="registerTable" />
function handleSummary(tableData: Recordable[]) {
const totalNo = tableData.reduce((prev, next) => {
prev += next.no;
return prev;
}, 0);
return [
{
_row: '合计',
_index: '平均值',
no: totalNo,
},
{
_row: '合计',
_index: '平均值',
no: totalNo,
},
];
}
const [registerTable] = useTable({
title: '表尾行合计示例',
api: demoListApi,
rowSelection: { type: 'checkbox' },
columns: getBasicColumns(),
showSummary: true,
summaryFunc: handleSummary,
scroll: { x: 2000 },
canResize: false,
showSelectionBar: true, // 显示多选状态栏
});
可编辑单元格
<BasicTable
@register="registerTable"
@edit-end="handleEditEnd"
@edit-cancel="handleEditCancel"
:beforeEditSubmit="beforeEditSubmit"
/>
const columns: BasicColumn[] = [
{
title: '输入框',
dataIndex: 'name',
edit: true,
editComponentProps: {
prefix: '$',
},
width: 200,
},
{
title: '默认输入状态',
dataIndex: 'name7',
edit: true,
editable: true,
width: 200,
},
{
title: '输入框校验',
dataIndex: 'name1',
edit: true,
// 默认必填校验
editRule: true,
width: 200,
},
{
title: '输入框函数校验',
dataIndex: 'name2',
edit: true,
editRule: async (text) => {
if (text === '2') {
return '不能输入该值';
}
return '';
},
width: 200,
},
{
title: '数字输入框',
dataIndex: 'id',
edit: true,
editRule: true,
editComponent: 'InputNumber',
width: 200,
editComponentProps: () => {
return {
max: 100,
min: 0,
};
},
editRender: ({ text }) => {
return h(Progress, { percent: Number(text) });
},
},
{
title: '下拉框',
dataIndex: 'name3',
edit: true,
editComponent: 'Select',
editComponentProps: {
options: [
{
label: 'Option1',
value: '1',
},
{
label: 'Option2',
value: '2',
},
],
},
width: 200,
},
{
title: '远程下拉',
dataIndex: 'name4',
edit: true,
editComponent: 'ApiSelect',
editComponentProps: {
api: optionsListApi,
resultField: 'list',
labelField: 'name',
valueField: 'id',
},
width: 200,
},
{
title: '远程下拉树',
dataIndex: 'name8',
edit: true,
editComponent: 'ApiTreeSelect',
editRule: false,
editComponentProps: {
api: treeOptionsListApi,
resultField: 'list',
},
width: 200,
},
{
title: '日期选择',
dataIndex: 'date',
edit: true,
editComponent: 'DatePicker',
editComponentProps: {
valueFormat: 'YYYY-MM-DD',
format: 'YYYY-MM-DD',
},
width: 200,
},
{
title: '时间选择',
dataIndex: 'time',
edit: true,
editComponent: 'TimePicker',
editComponentProps: {
valueFormat: 'HH:mm',
format: 'HH:mm',
},
width: 200,
},
{
title: '勾选框',
dataIndex: 'name5',
edit: true,
editComponent: 'Checkbox',
editValueMap: (value) => {
return value ? '是' : '否';
},
width: 200,
},
{
title: '开关',
dataIndex: 'name6',
edit: true,
editComponent: 'Switch',
editValueMap: (value) => {
return value ? '开' : '关';
},
width: 200,
},
{
title: '单选框',
dataIndex: 'radio1',
edit: true,
editComponent: 'RadioGroup',
editComponentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
width: 200,
},
{
title: '单选按钮框',
dataIndex: 'radio2',
edit: true,
editComponent: 'RadioButtonGroup',
editComponentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
width: 200,
},
{
title: '远程单选框',
dataIndex: 'radio3',
edit: true,
editComponent: 'ApiRadioGroup',
editComponentProps: {
api: optionsListApi,
resultField: 'list',
labelField: 'name',
valueField: 'id',
},
width: 200,
},
];
const [registerTable] = useTable({
title: '可编辑单元格示例',
api: demoListApi,
columns: columns,
showIndexColumn: false,
bordered: true,
});
可编辑行
<BasicTable @register="registerTable" @edit-change="onEditChange">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction :actions="createActions(record)" />
</template>
</template>
</BasicTable>
import {
BasicTable,
useTable,
TableAction,
BasicColumn,
ActionItem,
EditRecordRow,
} from '@/components/Table';
const columns: BasicColumn[] = [
{
title: '输入框',
dataIndex: 'name-group',
editRow: true,
children: [
{
title: '输入框',
dataIndex: 'name',
editRow: true,
editComponentProps: {
prefix: '$',
},
width: 150,
},
{
title: '默认输入状态',
dataIndex: 'name7',
editRow: true,
width: 150,
},
{
title: '输入框校验',
dataIndex: 'name1',
editRow: true,
align: 'left',
// 默认必填校验
editRule: true,
width: 150,
},
{
title: '输入框函数校验',
dataIndex: 'name2',
editRow: true,
align: 'right',
editRule: async (text) => {
if (text === '2') {
return '不能输入该值';
}
return '';
},
},
{
title: '数字输入框',
dataIndex: 'id',
editRow: true,
editRule: true,
editComponent: 'InputNumber',
width: 150,
},
],
},
{
title: '下拉框',
dataIndex: 'name3',
editRow: true,
editComponent: 'Select',
editComponentProps: {
options: [
{
label: 'Option1',
value: '1',
},
{
label: 'Option2',
value: '2',
},
{
label: 'Option3',
value: '3',
},
],
},
width: 200,
},
{
title: '远程下拉',
dataIndex: 'name4',
editRow: true,
editComponent: 'ApiSelect',
editComponentProps: {
api: optionsListApi,
resultField: 'list',
labelField: 'name',
valueField: 'id',
},
width: 200,
},
{
title: '远程下拉树',
dataIndex: 'name8',
editRow: true,
editComponent: 'ApiTreeSelect',
editRule: false,
editComponentProps: {
api: treeOptionsListApi,
resultField: 'list',
},
width: 200,
},
{
title: '日期选择',
dataIndex: 'date',
editRow: true,
editComponent: 'DatePicker',
editComponentProps: {
valueFormat: 'YYYY-MM-DD',
format: 'YYYY-MM-DD',
},
width: 150,
},
{
title: '时间选择',
dataIndex: 'time',
editRow: true,
editComponent: 'TimePicker',
editComponentProps: {
valueFormat: 'HH:mm',
format: 'HH:mm',
},
width: 100,
},
{
title: '勾选框',
dataIndex: 'name5',
editRow: true,
editComponent: 'Checkbox',
editValueMap: (value) => {
return value ? '是' : '否';
},
width: 100,
},
{
title: '开关',
dataIndex: 'name6',
editRow: true,
editComponent: 'Switch',
editValueMap: (value) => {
return value ? '开' : '关';
},
width: 100,
},
{
title: '单选框',
dataIndex: 'radio1',
editRow: true,
editComponent: 'RadioGroup',
editComponentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
width: 200,
},
{
title: '单选按钮框',
dataIndex: 'radio2',
editRow: true,
editComponent: 'RadioButtonGroup',
editComponentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
width: 200,
},
{
title: '远程单选框',
dataIndex: 'radio3',
editRow: true,
editComponent: 'ApiRadioGroup',
editComponentProps: {
api: optionsListApi,
resultField: 'list',
labelField: 'name',
valueField: 'id',
},
width: 200,
},
];
const [registerTable] = useTable({
title: '可编辑行示例',
titleHelpMessage: [
'本例中修改[数字输入框]这一列时,同一行的[远程下拉]列的当前编辑数据也会同步发生改变',
],
api: demoListApi,
columns: columns,
showIndexColumn: false,
showTableSetting: true,
tableSetting: { fullScreen: true },
actionColumn: {
width: 160,
title: 'Action',
dataIndex: 'action',
// slots: { customRender: 'action' },
},
});
function createActions(record: EditRecordRow): ActionItem[] {
if (!record.editable) {
return [
{
label: '编辑',
disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
onClick: handleEdit.bind(null, record),
},
];
}
return [
{
label: '保存',
onClick: handleSave.bind(null, record),
},
{
label: '取消',
popConfirm: {
title: '是否取消编辑',
confirm: handleCancel.bind(null, record),
},
},
];
}
function handleEdit(record: EditRecordRow) {
currentEditKeyRef.value = record.key;
record.onEdit?.(true);
}
function handleCancel(record: EditRecordRow) {
currentEditKeyRef.value = '';
record.onEdit?.(false, false);
}
async function handleSave(record: EditRecordRow) {
// 校验
msg.loading({ content: '正在保存...', duration: 0, key: 'saving' });
const valid = await record.onValid?.();
if (valid) {
try {
const data = cloneDeep(record.editValueRefs);
console.log(data);
//TODO 此处将数据提交给服务器保存
// ...
// 保存之后提交编辑状态
const pass = await record.onEdit?.(false, true);
if (pass) {
currentEditKeyRef.value = '';
}
msg.success({ content: '数据已保存', key: 'saving' });
} catch (error) {
msg.error({ content: '保存失败', key: 'saving' });
}
} else {
msg.error({ content: '请填写正确的数据', key: 'saving' });
}
}
继承父元素高度
isCanResizeParent属性值为true时,继承父级元素高度
<BasicTable @register="registerTable" />
const [registerTable] = useTable({
api: demoListApi,
columns: getBasicColumns(),
useSearchForm: false,
formConfig: getFormConfig(),
showTableSetting: false,
tableSetting: { fullScreen: true },
showIndexColumn: false,
isCanResizeParent: true,
rowKey: 'id',
});
useTable
const [register,{methods}] = useTable({table-params })
返回register和methods,register用于回显表格,methods中为表格的方法
table-methods
参数 | 说明 | 参数 | |
reload | 刷新数据 | 可传请求参数 | |
setProps | 修改表格的props | BasicTableProps | |
getColumns | 获取表头信息 | —— | |
setColumns | 设置表头 | 注意:推荐使用setProps | |
clearSelectedRowKeys | 清空已选表格行 | —— | |
updateTableDataRecord | 不刷新表格直接更新内部数据 | keyValue,record | 注意: updateTableDataRecord 要求表格的rowKey属性为 string并且存在于每一行的 record的keys中 |
getForm | 获取表单数据 | —— |
table-params
参数 | 说明 | 类型 | 默认值 |
clickToRowSelect | 点击行选中 | boolean | true |
isTreeTable | 树形表格 | boolean | false |
accordion | 手风琴效果 | boolean | false,isTreeTable 或 expandRowByClick 时支持 |
sortFn | 自定义排序方法 | Function | |
filterFn | 排序方法 | Function | |
inset | 取消表格的默认padding | boolean | false |
showTableSetting | 显示表格设置 | boolean | false |
tableSetting | 设置表格设置 | TableSetting | |
striped | 斑马纹 | boolean | false |
autoCreateKey | 是否自动生成key | boolean | true |
summaryFunc | 计算合计行的方法 | ||
summaryData | 自定义合计表格内容 | ||
showSummary | 是否显示合计行 | boolean | false |
canColDrag | 是否可拖拽列 | boolean | false |
api | 接口请求对象 | Promise | |
beforeFetch | 请求之前处理参数 | Fn | |
afterFetch | 自定义处理接口返回参数 | Fn | |
handleSearchInfoFn | 查询条件请求之前处理 | Fn | |
fetchSetting | 请求接口配置 | Object | |
immediate | 立即请求接口 | boolean | true |
emptyDataIsShowTable | 在开起搜索表单的时候,如果没有数据是否显示表格 | boolean | true |
searchInfo | 额外的请求参数 | Object | |
defSort | 默认的排序参数 | Object | |
useSearchForm | 使用搜索表单 | boolean | false |
formConfig | 表单配置 | Object | |
columns | 列配置 | BasicColumn | |
showIndexColumn | 是否显示序号列 | boolean | false |
indexColumnProps | 序号列配置 | Object | |
actionColumn | Object | ||
ellipsis | 文本超过宽度是否显示。。。 | boolean | true |
isCanResizeParent | 是否继承父级高度(父级高度-表单高度-padding高度) | boolean | false |
canResize | 是否可以自适应高度 | boolean | true |
resizeHeightOffset | 自适应高度偏移, 计算结果-偏移量 | number | |
minHeight | 设置表格高度最小值 | number | 0 |
clearSelectOnPageChange | 在分页改变的时候清空选项 | boolean | undefined |
rowKey | 表格主键 | ||
dataSource | 数据 | ||
titleHelpMessage | 标题右侧提示 | string | |
maxHeight | 表格滚动最大高度 | number | |
bordered | 是否显示边框 | boolean | |
pagination | 分页配置 | PaginationProps | boolean | |
loading | loading加载 | boolean | |
childrenColumnName | 指定树形结构的列名 | string | 表格支持树形数据的展示,当数据中有 children 字段时会自动展示为树形表格,如果不需要或配置为其他字段可以用 childrenColumnName 进行配置。 可以通过设置 indentSize 以控制每一层的缩进宽度 |
components | 覆盖默认的 table 元素 | object | |
defaultExpandAllRows | 初始时,是否展开所有行 | boolean | |
defaultExpandedRowKeys | 默认展开的行 | string[] | |
expandedRowKeys | 展开的行,控制属性 | string[] | |
expandedRowRender | 额外的展开行 | Function(record, index, indent, expanded):VNode | v-slot:expandedRowRender="{record, index, indent, expanded}" | |
expandIcon | 自定义展开图标 | Fn | |
expandRowByClick | 通过点击行来展开子行 | boolean | |
expandIconColumnIndex | ‘expandIcon’的索引,当‘expandIconAsCell’为false时,将插入哪个列。默认值0 | number | |
footer | 表格尾部 | Fn | |
indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | |
locale | 默认文案设置,目前包括排序、过滤、空数据文案 | object | |
rowClassName | 表格行的类名 | ||
rowSelection | 列表项是否可选择,配置项 | TableRowSelection | |
showSelectionBar | 显示多选状态栏 | boolean | |
scroll | 表格是否可滚动,也可以指定滚动区域的宽、高,配置项 | ||
showHeader | 是否显示表头 | boolean | true |
size | 表格大小 | large | middle | small | |
title | 表格头部标题 | string | |
customHeaderRow | 设置头部行属性 | object | |
customRow | 设置行属性 | object | |
tableLayout | 表格元素的 table-layout 属性,设为 fixed 表示内容不会影响列的布局 | - | 'auto' | 'fixed' | |
getPopupContainer | 设置表格内各类浮层的渲染节点,如筛选菜单 | ||
transformCellText | 数据渲染前可以再次改变,一般用于空数据的默认配置,可以通过 ConfigProvider 全局统一配置 | Function | |
beforeEditSubmit | 提交表格数据前触发 | ||
onChange | |||
onExpand | |||
onExpandedRowsChange | |||
onColumnsChange |
formConfig
参数 | 说明 | 类型 | 默认值 |
name | string | ||
layout | 'vertical' | 'inline' | 'horizontal' | string | horizontal |
labelWidth | lable的宽度 | number | string | |
labelAlign | lable文字对齐方向 | 'left' | 'right' | |
rowProps | 整个表单的alignRow配置 | obj | 具体参考 rowProps配置项 |
submitOnReset | 重置时提交表格 | boolean | true |
labelCol | 整个表单的Col配置 | ColEx | |
baseRowStyle | 通用行风格 | CSSProperties | |
baseColProps | 通用col配置 | ColEx | |
schemas | 表单配置规则 | FormSchema | |
mergeDynamicData | 用于合并到动态控件窗体项中的函数值 | Object | |
compact | 搜索表格的精简模式 | boolean | |
emptySpan | 空白行跨度 | number | |
size | 表单的内部组件大小 | 'default' | 'small' | 'large' | |
disabled | 是否禁用 | boolean | false |
readonly | 是否只读 | boolean | false |
fieldMapToTime | 时间间隔字段映射到多个 | FieldMapToTime | [string, [string, string], (string | [string, string])?] |
autoSetPlaceHolder | 占位符是自动设置的 | boolean | |
autoSubmitOnEnter | 输入时按回车键自动提交 | boolean | |
rulesMessageJoinLabel | 检查该信息是否添加到标签上 | boolean | |
showAdvancedButton | 是否显示折叠和展开按钮 | boolean | false |
autoFocusFirstItem | 是否关注第一个输入框,只在输入第一个表单项时才起作用 | boolean | |
autoAdvancedLine | 在指定的行数上自动折叠 | number | |
alwaysShowLines | 始终显示行数 | number | |
showActionButtonGroup | 是否显示操作按钮 | boolean | |
resetButtonOptions | 重置按钮配置 | {text:string} | |
submitButtonOptions | 确认按钮配置 | {text:string} | |
actionColOptions | 操作列配置 | ||
showResetButton | 展示重置按钮 | boolean | TRUE |
showSubmitButton | 展示查询按钮 | boolean | TRUE |
rowProps
align | "top" | "bottom" | "stretch" | "middle" |
justify | "center" | "end" | "start" | "space-around" | "space-between" | "space-evenly" |
gutter | number |
wrap |