Table 表格
基于 ant-design-vue Table 封装,内置 CRUD、表单搜索、表头排序、数据导入导出等功能
示例前提配置
tsx
import { TableConfig } from 'antd-vue-dbthor'
export default () => {
TableConfig.indexColumnWidth = 40
TableConfig.controlColumnWidth = 150
TableConfig.cuFormProps = {
labelCol: {
span: 4,
},
}
TableConfig.fieldsNames = {
...TableConfig.fieldsNames,
list: ['data', 'data', 'list'],
total: ['data', 'data', 'total'],
details: ['data', 'data'],
}
TableConfig.queryFormItemsControlProps = {
autoComplete: 'off',
}
}
ts
import Axios from 'axios'
const axios = Axios.create({
baseURL: import.meta.env.VITE_REQUEST_BASE_URL,
})
axios.interceptors.request.use((req) => {
return req
})
axios.interceptors.response.use((res) => {
return res
})
export default axios
ts
import axios from './request'
export const getUsersPageApi = async (params?: any, config?: any) =>
await axios.get('/public/users/page', { params, ...config })
export const createUserApi = async (data?: any, config?: any) =>
await axios.post('/public/users', data, config)
export const updateUserApi = async ({ id, ...data }: any, config?: any) =>
await axios.put(`/public/users/${id}`, data, config)
export const deleteUserApi = async ({ id }: any, config?: any) =>
await axios.delete(`/public/users/${id}`)
export const getUserDetailsApi = async (params?: any, config?: any) =>
await axios.get('/public/users', { params, ...config })
export const downloadUserTemplateByBufferApi = async (params?: any, config?: any) =>
await axios.get('/public/users/template/buffer', { params, ...config })
export const downloadUserTemplateByBlobApi = async (params?: any) =>
await axios.get('/public/users/template/blob', {
responseType: 'blob',
})
export const exportUsersByBufferApi = async (params?: any, config?: any) =>
await axios.get('/public/users/export-excel', { params, ...config })
export const exportUsersByBlobApi = async (params?: any, config?: any) =>
await axios.get('/public/users/export-excel', { params, responseType: 'blob' })
export const importUserApi = async (data?: any, config?: any) =>
await axios.post('/public/users/import-excel', data, {
...config,
headers: {
'content-type': 'multipart/form-data',
},
})
本页示例均基于以上配置编写
基本用法
Code
vue
<template>
<Table
ref="tableRef"
columns-align="center"
:index-column-width="60"
:columns="columns"
:query-form-items="queryFormItems"
template-file-name="用户列表模板.xlsx"
export-file-name="用户列表数据.xlsx"
:apis="apis"
>
<template #customCiesBtns="{ CreateBtn, ImportBtn, ExportAllBtn, DownloadTemplateBtn }">
<Space>
<component :is="CreateBtn" />
<component :is="ImportBtn" />
<component :is="ExportAllBtn" />
<component :is="DownloadTemplateBtn" />
<Button @click="() => tableRef.resetPage()">重置分页</Button>
<Button @click="() => tableRef.updateSource()">刷新列表</Button>
</Space>
</template>
</Table>
</template>
<script setup lang="tsx">
import {
createUserApi,
deleteUserApi,
downloadUserTemplateByBlobApi,
exportUsersByBufferApi,
getUserDetailsApi,
getUsersPageApi,
importUserApi,
updateUserApi,
} from '@docs/apis/user'
import { Button, Space } from 'ant-design-vue'
import { ControlMapType, Table, TableProps } from 'antd-vue-dbthor'
import { computed, ref } from 'vue'
const tableRef = ref<InstanceType<typeof Table>>() // 表格实例
const apis = ref<TableProps['apis']>({
list: getUsersPageApi,
details: getUserDetailsApi,
create: createUserApi,
update: updateUserApi,
delete: deleteUserApi,
template: downloadUserTemplateByBlobApi,
export: exportUsersByBufferApi,
import: importUserApi,
})
const sexOptions = [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]
const columns = computed((): TableProps['columns'] => {
return [
{
title: 'id',
dataIndex: 'id',
hidden: true,
formItemProps: {
hidden: true,
},
descItemProps: {
hidden: true,
},
},
{
title: '用户名',
dataIndex: 'username',
width: 100,
},
{
title: '昵称',
width: 100,
dataIndex: 'nickname',
},
{
title: '年龄',
dataIndex: 'age',
type: 'number',
formItemProps: {
control: ControlMapType.InputNumber,
},
width: 100,
},
{
title: '性别',
dataIndex: 'sex',
formItemProps: {
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
},
},
width: 100,
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label,
},
{
title: '职业',
dataIndex: 'occupation',
width: 100,
},
]
})
const queryFormItems = computed((): TableProps['queryFormItems'] => [
{
label: '用户名',
name: 'username',
},
{
label: '昵称',
name: 'nickname',
},
{
label: '年龄',
name: 'age',
},
{
label: '性别',
name: 'sex',
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
style: {
width: '120px',
},
},
},
])
</script>
<style scoped></style>
取值配置
INFO
表格内置了新增改查/下载模板/导出/导入逻辑功能,在配置了 apis 后需要根据请求返回值的数据结构来配置取值方式
配置表格的取值主要有两种方式:
- fieldsNames
- Event (优先级 > fieldsNames )
- fieldsNames.list 和 fieldsNames.total 两个字段比较特殊,在使用@source-success 回填字段时需结合 fieldsNames,使它们能对应上
Code
vue
<template>
<Table
:columns="columns"
:query-form-items="queryFormItems"
:apis="apis"
:fieldsNames="{
...TableConfig.fieldsNames, // [!code focus]
list: ['data', 'list'], // [!code focus]
total: ['data', 'total'], // [!code focus]
details: ['data'], // [!code focus]
}"
></Table>
</template>
<script setup lang="tsx">
import Axios from 'axios'
const axios = Axios.create({
baseURL: import.meta.env.VITE_REQUEST_BASE_URL,
})
axios.interceptors.response.use((resp) => resp.data)
import { ControlMapType, Table, TableConfig, TableProps } from 'antd-vue-dbthor'
import { computed, ref } from 'vue'
const apis = ref({
list: async (params?: any) => await axios.get('/public/users/page', { params }),
details: async (params?: any) => await axios.get('/public/users', { params }),
create: async (data?: any) => await axios.post('/public/users', data),
update: async ({ id, ...data }: any) => await axios.put(`/public/users/${id}`, data),
delete: async ({ id }: any) => await axios.delete(`/public/users/${id}`),
})
const sexOptions = [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]
const columns = computed((): TableProps['columns'] => {
return [
{
title: 'id',
dataIndex: 'id',
hidden: true,
formItemProps: {
hidden: true,
},
descItemProps: {
hidden: true,
},
},
{
title: '用户名',
dataIndex: 'username',
width: 100,
},
{
title: '昵称',
width: 100,
dataIndex: 'nickname',
},
{
title: '年龄',
width: 100,
dataIndex: 'age',
type: 'number',
formItemProps: {
control: ControlMapType.InputNumber,
},
},
{
title: '性别',
width: 100,
dataIndex: 'sex',
formItemProps: {
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
},
},
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label,
},
{
title: '职业',
width: 100,
dataIndex: 'occupation',
},
]
})
const queryFormItems = computed((): TableProps['queryFormItems'] => [
{
label: '用户名',
name: 'username',
},
{
label: '昵称',
name: 'nickname',
},
{
label: '年龄',
name: 'age',
},
{
label: '性别',
name: 'sex',
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
style: {
width: '120px',
},
},
},
])
</script>
<style scoped></style>
vue
<template>
<Table
:columns="columns"
:query-form-items="queryFormItems"
:apis="apis"
@source-success="onSourceSuccess"
@get-row-detail="onGetRowDetail"
:fields-names="{
...TableConfig.fieldsNames,
list: 'custom-data-source',
total: 'custom-total-name',
}"
></Table>
</template>
<script setup lang="tsx">
import {
createUserApi,
deleteUserApi,
getUserDetailsApi,
getUsersPageApi,
updateUserApi,
} from '@docs/apis/user'
import { ControlMapType, Table, TableConfig, TableProps } from 'antd-vue-dbthor'
import { AxiosResponse } from 'axios'
import { computed, ref } from 'vue'
const apis = ref({
list: getUsersPageApi,
details: getUserDetailsApi,
create: createUserApi,
update: updateUserApi,
delete: deleteUserApi,
})
const onSourceSuccess = async (res: AxiosResponse) => {
// 返回的对象将作为表格数据/总数的取值源, 需匹配fieldsNames
return {
'custom-data-source': res?.data?.data?.list,
'custom-total-name': res?.data?.data?.total,
}
}
const onGetRowDetail = async (res: AxiosResponse) => {
// 获取的单行详情直接返回要渲染的数据即可
return res?.data?.data
}
const sexOptions = [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]
const columns = computed((): TableProps['columns'] => {
return [
{
title: 'id',
dataIndex: 'id',
hidden: true,
formItemProps: {
hidden: true,
},
descItemProps: {
hidden: true,
},
},
{
title: '用户名',
dataIndex: 'username',
width: 100,
},
{
title: '昵称',
width: 100,
dataIndex: 'nickname',
},
{
title: '年龄',
width: 100,
dataIndex: 'age',
type: 'number',
formItemProps: {
control: ControlMapType.InputNumber,
},
},
{
title: '性别',
width: 100,
dataIndex: 'sex',
formItemProps: {
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
},
},
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label,
},
{
title: '职业',
width: 100,
dataIndex: 'occupation',
},
]
})
const queryFormItems = computed((): TableProps['queryFormItems'] => [
{
label: '用户名',
name: 'username',
},
{
label: '昵称',
name: 'nickname',
},
{
label: '年龄',
name: 'age',
},
{
label: '性别',
name: 'sex',
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
style: {
width: '120px',
},
},
},
])
</script>
<style scoped></style>
导出、下载模板
Code
vue
<template>
<Table columns-align="center" :columns="columns" :query-form-items="queryFormItems" template-file-name="用户列表模板.xlsx"
export-file-name="用户列表数据.xlsx" :apis="apis">
</Table>
</template>
<script setup lang="tsx">
import {
createUserApi,
deleteUserApi,
getUserDetailsApi,
getUsersPageApi,
updateUserApi,
downloadUserTemplateByBlobApi,
exportUsersByBlobApi,
} from '@docs/apis/user'
import { ControlMapType, Table, TableProps } from 'antd-vue-dbthor'
import { computed, ref } from 'vue'
const apis = ref<TableProps['apis']>({
list: getUsersPageApi,
details: getUserDetailsApi,
create: createUserApi,
update: updateUserApi,
delete: deleteUserApi,
template: downloadUserTemplateByBlobApi,
export: exportUsersByBlobApi
})
const sexOptions = [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]
const columns = computed((): TableProps['columns'] => {
return [
{
title: 'id',
dataIndex: 'id',
hidden: true,
formItemProps: {
hidden: true,
},
descItemProps: {
hidden: true,
},
},
{
title: '用户名',
dataIndex: 'username',
width: 100,
},
{
title: '昵称',
width: 100,
dataIndex: 'nickname',
},
{
title: '年龄',
width: 100,
dataIndex: 'age',
type: 'number',
formItemProps: {
control: ControlMapType.InputNumber,
},
},
{
title: '性别',
width: 100,
dataIndex: 'sex',
formItemProps: {
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
},
},
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label,
},
{
title: '职业',
width: 100,
dataIndex: 'occupation',
},
]
})
const queryFormItems = computed((): TableProps['queryFormItems'] => [
{
label: '用户名',
name: 'username',
},
{
label: '昵称',
name: 'nickname',
},
{
label: '年龄',
name: 'age',
},
{
label: '性别',
name: 'sex',
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
style: {
width: '120px',
},
},
},
])
</script>
<style scoped></style>
vue
<template>
<Table columns-align="center" :columns="columns" :query-form-items="queryFormItems" template-file-name="用户列表模板.xlsx"
export-file-name="用户列表数据.xlsx" :apis="apis" @template-request-success="onTemplateRequestSuccess">
</Table>
</template>
<script setup lang="tsx">
import {
createUserApi,
deleteUserApi,
getUserDetailsApi,
getUsersPageApi,
updateUserApi,
downloadUserTemplateByBufferApi,
exportUsersByBufferApi,
} from '@docs/apis/user'
import { ControlMapType, Table, TableProps } from 'antd-vue-dbthor'
import { AxiosResponse } from 'axios'
import { computed, ref } from 'vue'
const apis = ref<TableProps['apis']>({
list: getUsersPageApi,
details: getUserDetailsApi,
create: createUserApi,
update: updateUserApi,
delete: deleteUserApi,
template: downloadUserTemplateByBufferApi,
export: exportUsersByBufferApi
})
const onTemplateRequestSuccess = async ({ data, headers }: AxiosResponse) => {
const blob = new Blob([new Uint8Array(data?.data?.data)], {
type: headers['content-type'],
})
const thumbUrl = URL.createObjectURL(blob)
return {
thumbUrl,
}
}
const sexOptions = [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]
const columns = computed((): TableProps['columns'] => {
return [
{
title: 'id',
dataIndex: 'id',
hidden: true,
formItemProps: {
hidden: true,
},
descItemProps: {
hidden: true,
},
},
{
title: '用户名',
dataIndex: 'username',
width: 100,
},
{
title: '昵称',
width: 100,
dataIndex: 'nickname',
},
{
title: '年龄',
width: 100,
dataIndex: 'age',
type: 'number',
formItemProps: {
control: ControlMapType.InputNumber,
},
},
{
title: '性别',
width: 100,
dataIndex: 'sex',
formItemProps: {
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
},
},
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label,
},
{
title: '职业',
width: 100,
dataIndex: 'occupation',
},
{
title: '创建时间',
dataIndex: 'createTime',
type: 'date',
width: 100,
},
{
title: '更新时间',
dataIndex: 'updateTime',
type: 'date',
width: 100,
},
]
})
const queryFormItems = computed((): TableProps['queryFormItems'] => [
{
label: '用户名',
name: 'username',
},
{
label: '昵称',
name: 'nickname',
},
{
label: '年龄',
name: 'age',
},
{
label: '性别',
name: 'sex',
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
style: {
width: '120px',
},
},
},
])
</script>
<style scoped></style>
拓展、自定义按钮
Code
vue
<template>
<Table :index-column-width="80" :control-column-width="400" columns-align="center" :columns="columns"
:query-form-items="queryFormItems" template-file-name="用户列表模板.xlsx" export-file-name="用户列表数据.xlsx" :apis="apis"
:scroll="{
x: 'auto',
y: 'auto'
}">
<!-- 查询表单按钮 -->
<template #customQueryFormBtns="{ SubmitBtn, ResetBtn, QueryFormInstance }">
<Space>
<Button @click="() => hellow(QueryFormInstance)">Hellow</Button>
<component :is="SubmitBtn" :style="{
background: 'green'
}" />
<component type="primary" :is="ResetBtn" danger />
</Space>
</template>
<!-- cies区域 -->
<template
#customCiesBtns="{ CreateBtn, ImportBtn, ExportAllBtn, ExportCurrentPageBtn, ExportDropDown, DownloadTemplateBtn, ColumnSettingBtn }">
<Space>
<component :is="CreateBtn" type="primary" :style="{
background: '#ff7875'
}" />
<component :is="ImportBtn" type="primary" :style="{
background: '#ff9c6e'
}" />
<component :is="ExportAllBtn" type="primary" :style="{
background: '#ffc069'
}" />
<component :is="ExportCurrentPageBtn" type="primary" :style="{
background: '#d4b106'
}" />
<component :is="ExportDropDown" :buttonProps="{
type: 'primary',
style: {
background: '#36cfc9'
}
}" placement="topLeft" :trigger="['click']" />
<component :is="DownloadTemplateBtn" type="primary" :style="{
background: '#4096ff'
}" />
<component :is="ColumnSettingBtn" :buttonProps="{
type: 'primary',
style: {
background: '#9254de'
}
}" :trigger="['click']" placement="rightTop" />
<Button type="primary">自定义1</Button>
</Space>
</template>
<!-- 操作列 -->
<template
#customControlColumnBtns="{ DetailBtn, EditBtn, DeleteBtn, openRowDetails, editRow, deleteRow, rowInfo }">
<Button type="link" @click="() => openRowDetails(rowInfo?.record)" size="small">详情</Button>
<Button type="link" @click="() => editRow(rowInfo?.record)" size="small">编辑</Button>
<Button type="link" @click="() => deleteRow(rowInfo?.record)" size="small" danger>删除</Button>
<component :is="DetailBtn" type="primary" size="small" />
<component :is="EditBtn" type="primary" size="small" />
<component :is="DeleteBtn" type="primary" size="small" />
</template>
</Table>
</template>
<script setup lang="tsx">
defineOptions({
name: 'extended-btns'
})
import {
createUserApi,
deleteUserApi,
downloadUserTemplateByBlobApi,
exportUsersByBufferApi,
getUserDetailsApi,
getUsersPageApi,
importUserApi,
updateUserApi,
} from '@docs/apis/user'
import { TableQueryFormInstance } from '@src/components/table/useQueryForm'
import { Button, message, Space } from 'ant-design-vue'
import { ControlMapType, Table, TableProps } from 'antd-vue-dbthor'
import { computed, ref } from 'vue'
const apis = ref<TableProps['apis']>({
list: getUsersPageApi,
details: getUserDetailsApi,
create: createUserApi,
update: updateUserApi,
delete: deleteUserApi,
template: downloadUserTemplateByBlobApi,
export: exportUsersByBufferApi,
import: importUserApi
})
const sexOptions = [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]
const columns = computed((): TableProps['columns'] => {
return [
{
title: 'id',
dataIndex: 'id',
hidden: true,
formItemProps: {
hidden: true,
},
descItemProps: {
hidden: true,
},
},
{
title: '用户名',
dataIndex: 'username',
width: 300,
},
{
title: '昵称',
width: 300,
dataIndex: 'nickname',
},
{
title: '年龄',
dataIndex: 'age',
type: 'number',
formItemProps: {
control: ControlMapType.InputNumber,
},
width: 300,
},
{
title: '性别',
dataIndex: 'sex',
formItemProps: {
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
},
},
width: 300,
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label,
},
{
title: '职业',
dataIndex: 'occupation',
width: 300,
},
{
title: "创建时间",
dataIndex: 'createTime',
type: 'date',
width: 300,
formItemProps: {
hidden: true
}
},
{
title: "更新时间",
dataIndex: 'updateTime',
type: 'date',
width: 300,
formItemProps: {
hidden: true
}
}
]
})
const queryFormItems = computed((): TableProps['queryFormItems'] => [
{
label: '用户名',
name: 'username',
},
{
label: '昵称',
name: 'nickname',
},
{
label: '年龄',
name: 'age',
},
{
label: '性别',
name: 'sex',
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
style: {
width: '120px',
},
},
},
])
const hellow = (QueryFormInstance: TableQueryFormInstance) => {
message.info(`hellow username is ${QueryFormInstance.getFieldsValue([['username']])?.username}`)
}
</script>
<style scoped></style>
单元格编辑
Code
vue
<template>
<Table :index-column-width="80" :control-column-width="200" v-model:value="value" columns-align="center"
:columns="columns" :query-form-items="queryFormItems" template-file-name="用户列表模板.xlsx"
export-file-name="用户列表数据.xlsx" :apis="apis">
</Table>
<Table :index-column-width="80" :cies-btns="false" :own-pagin="false" columns-align="center" :query-form="false"
:control-column="false" :data-source="value" bordered :columns="columns1"></Table>
</template>
<script setup lang="tsx">
import {
createUserApi,
deleteUserApi,
downloadUserTemplateByBlobApi,
exportUsersByBufferApi,
getUserDetailsApi,
getUsersPageApi,
importUserApi,
updateUserApi,
} from '@docs/apis/user'
import { ControlMapType, Table, TableProps } from 'antd-vue-dbthor'
import { computed, ref } from 'vue'
const value = ref<TableProps['dataSource']>([])
const apis = ref<TableProps['apis']>({
list: getUsersPageApi,
details: getUserDetailsApi,
create: createUserApi,
update: updateUserApi,
delete: deleteUserApi,
template: downloadUserTemplateByBlobApi,
export: exportUsersByBufferApi,
import: importUserApi
})
const sexOptions = [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]
const columns = computed((): TableProps['columns'] => {
return [
{
title: 'id',
dataIndex: 'id',
hidden: true,
formItemProps: {
hidden: true,
},
descItemProps: {
hidden: true,
},
},
{
title: '用户名',
dataIndex: 'username',
width: 200,
editable: true,
editControlProps: {
bordered: false
}
},
{
title: '昵称',
width: 100,
dataIndex: 'nickname',
editable: true
// editable 默认会取formItemProps中的控件配置
},
{
title: '年龄',
dataIndex: 'age',
type: 'number',
formItemProps: {
control: ControlMapType.InputNumber,
},
width: 100,
editable: true,
},
{
title: '性别',
dataIndex: 'sex',
formItemProps: {
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
allowClear: false
},
},
width: 150,
editable: true,
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label,
},
{
title: '职业',
dataIndex: 'occupation',
width: 100,
},
{
title: "创建时间",
dataIndex: 'createTime',
type: 'date',
width: 200,
formItemProps: {
hidden: true
},
},
{
title: "更新时间",
dataIndex: 'updateTime',
type: 'date',
width: 200,
formItemProps: {
control: ControlMapType.DatePicker,
controlProps: {
showTime: true
}
},
editable: true,
},
{
title: '时间范围',
dataIndex: [['createTime'], ['updateTime']],
type: 'date-range',
width: 400,
formItemProps: {
name: "createTime-updateTime",
control: ControlMapType.RangePicker,
controlProps: {
showTime: true
}
},
editable: true,
}
]
})
const columns1 = computed(() => columns.value.map((item => ({ ...item, editable: false }))))
const queryFormItems = computed((): TableProps['queryFormItems'] => [
{
label: '用户名',
name: 'username',
},
{
label: '昵称',
name: 'nickname',
},
{
label: '年龄',
name: 'age',
},
{
label: '性别',
name: 'sex',
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
style: {
width: '120px',
},
},
},
{
label: '时间范围',
name: "createTime-updateTime",
control: ControlMapType.RangePicker,
}
])
</script>
<style scoped></style>
内置表单自定义控件
Code
vue
<template>
<Table columns-align="center" :index-column-width="60" :control-column-width="180" :columns="columns"
:query-form-items="queryFormItems" template-file-name="用户列表模板.xlsx" export-file-name="用户列表数据.xlsx" :apis="apis"
@before-cu-form-submit="onBeforeSubmit">
</Table>
</template>
<script setup lang="tsx">
import {
createUserApi,
deleteUserApi,
downloadUserTemplateByBlobApi,
exportUsersByBufferApi,
getUserDetailsApi,
getUsersPageApi,
importUserApi,
updateUserApi,
} from '@docs/apis/user'
import { Button, Divider, Flex, Form } from 'ant-design-vue'
import { ControlMapType, Table, TableProps } from 'antd-vue-dbthor'
import dayjs from 'dayjs'
import { computed, ref } from 'vue'
const apis = ref<TableProps['apis']>({
list: getUsersPageApi,
details: getUserDetailsApi,
create: createUserApi,
update: updateUserApi,
delete: deleteUserApi,
template: downloadUserTemplateByBlobApi,
export: exportUsersByBufferApi,
import: importUserApi
})
const sexOptions = [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]
const columns = computed((): TableProps['columns'] => {
return [
{
title: 'id',
dataIndex: 'id',
hidden: true,
formItemProps: {
hidden: true,
},
descItemProps: {
hidden: true,
},
},
{
title: '用户名',
dataIndex: 'username',
width: 100,
formItemProps: {
// 新增/编辑表单中自定义控件
customControl: ({ dataIndex }, model) => {
return <CustomControl v-model={model.values[`${dataIndex}`]}></CustomControl>
},
}
},
{
title: '昵称',
width: 100,
dataIndex: 'nickname',
formItemProps: {
hidden: true
}
},
{
title: '年龄',
dataIndex: 'age',
type: 'number',
formItemProps: {
hidden: true
},
width: 100,
},
{
title: '性别',
dataIndex: 'sex',
formItemProps: {
hidden: true
},
width: 100,
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label,
},
{
title: '职业',
dataIndex: 'occupation',
width: 100,
formItemProps: {
hidden: true,
},
},
{
title: '这是一个不显示的表头',
hidden: true,
formItemProps: {
name: 'userList',
// 当自定义控件不足需求时,还可以自定义整个单元格内的内容,比如将其他字段全部隐藏
colProps: {
span: 24, // 调整该占满整行
},
customRender: (model, form) => {
const add = () => {
const initValue = {
id: dayjs().valueOf(),
username: void 0,
nickname: void 0,
age: void 0,
sex: void 0,
occupation: void 0
}
if (Array.isArray(model.values['userList'])) {
model.values['userList'].push(initValue)
} else {
model.values['userList'] = [initValue]
}
}
const removeRow = ({id}) => {
const index = model.values.userList?.findIndex((item) => item.id === id )
model.values.userList.splice(index,1)
}
return <Flex vertical>
<Divider >请填写用户列表</Divider>
<Form.Item name="userList">
<Table size="small" tableLayout='auto' scroll={{
y: undefined
}} columns={[
{
title: '用户名',
dataIndex: 'username',
width: 100,
editable: true
},
{
title: '昵称',
width: 100,
dataIndex: 'nickname',
editable: true
},
{
title: '年龄',
dataIndex: 'age',
type: 'number',
width: 100,
editable: true,
editControl: ControlMapType.InputNumber
},
{
title: '性别',
dataIndex: 'sex',
width: 100,
editable: true,
editControl: ControlMapType.Select,
editControlProps: {
options: sexOptions
},
customRender: ({ text }) => sexOptions?.find?.(({ value }) => value === text)?.label || '-',
},
{
title: '职业',
dataIndex: 'occupation',
width: 100,
editable: true,
},
{
title:'操作',
type:'control',
width: 100,
customRender: ({record}:any) => {
return <Button size="small" danger onClick={() =>removeRow(record) }>删除</Button>
}
}
]} ownPagin={false} columnSettingBtn={false} indexColumn={false} controlColumn={false} queryForm={false} autoRequest={false} v-model:value={model.values['userList']} >
</Table>
<Button class="ml-2" onClick={() => add()}>新增一行</Button>
</Form.Item>
</Flex>
},
}
}
]
})
const onBeforeSubmit = async (vals) => {
// 处理成接口需要的格式返回
return vals
// return false 则不执行内置的提交处理
}
const CustomControl = (props, { emit }) => {
const onChange = ({ target }) => {
emit('update:modelValue', target.value)
}
return <input value={props.modelValue} class="border border-solid p-1 rounded border-yellow-500" onChange={onChange}></input>
}
const queryFormItems = computed((): TableProps['queryFormItems'] => [
{
label: '用户名',
name: 'username',
customControl: (model, name) => {
// 查询表单中自定义控件
return <CustomControl v-model={model.values[`${name}`]}></CustomControl>
},
},
{
label: '昵称',
name: 'nickname',
},
{
label: '年龄',
name: 'age',
},
{
label: '性别',
name: 'sex',
control: ControlMapType.Select,
controlProps: {
options: sexOptions,
style: {
width: '120px',
},
},
},
])
</script>
<style scoped></style>
Props
Table
参数 | 说明 | 类型 | 默认值 | 版本 | global |
---|---|---|---|---|---|
... | 继承 antd-vue TableProps | - | - | - | - |
full | 表格是否撑满容器 | boolean | false | - | * |
scroll | 表格是否可滚动,也可以指定滚动区域的宽、高 配置项 | object | - | - | * |
autoSizeConfig | 表格自动计算高度函数防抖配置 配置项 | object | - | - | * |
minScollHeight | 指定自动计算表格 scroll.y 值的最小高度, scroll.y 指定为 number 时该值不生效 | number | 50 | - | * |
autoRequest | 指定表格自动请求列表数据配置 配置项 | false / object | - | - | * |
autoRequestDependencies | 自定义表格自动请求列表数的依赖项 | ({params,apis}) => WatchSource | - | - | * |
apis | 提供给表格内置请求的 api 配置项 | object | - | - | - |
fieldsNames | 配置表格调用 api 后从返回结果中拿取数据的字段 配置项 | object | - | - | * |
tableTextConfig | 配置表格内置提示的文本 配置项 | object | - | - | * |
params | 请求时额外添加的参数 | object | - | - | - |
columns | 表格列配置 | TableColumnProps[] | - | - | - |
columnsTitleNoWrap | 统一列头不换行 | boolean | true | - | * |
columnsAlign | 统一列对齐方式 | 'left' / 'center' / 'right' | 'left' | - | * |
columnsSorter | 统一列排序配置, 除['index','control']列,其他列均内置了排序逻辑 | ColumnProps['sorter'] | true | - | * |
columnsEllipsis | 统一列的 ellipsis 属性 | boolean | true | - | * |
columnsTimeFormat | 当 column.type == 'date'时,处理时间显示的格式 | string | 'YYYY-MM-DD HH:mm:ss' | - | * |
columnsEmptyText | 统一列取值为空时显示的内容 | VNode / string | '-' | - | * |
indexColumn | 开启序号列 | boolean | true | - | * |
indexColumnWidth | 序号列宽度 | number | 80 | - | * |
indexColumnProps | 序号列 Props | TableColumnProps | - | - | * |
controlColumn | 开启操作列 | boolean | true | - | * |
controlColumnWidth | 操作列宽度 | number | 220 | - | * |
controlColumnWidthProps | 操作列 Props | TableColumnProps | - | - | * |
controlColumnBtns | 操作列按钮配置项 | controlColumnBtns | - | - | * |
columnSettingBtn | 列配置按钮 | false / OwnPopoverProps | true | - | * |
showOwnPager | 显示内置分页器 | boolean | true | - | * |
ownPagin | 开启内置分页,值为 false 时请求数据参数将不加入分页参数 | boolean | true | - | * |
ownPaginProps | 内置分页器 Props | paginationProps | object | - | * |
queryForm | 显示筛选表单 | boolean | true | - | * |
queryFormDefaultValues | 筛选表单默认值 | object | - | - | - |
queryFormProps | 筛选表单的 Props | FormProps | - | - | * |
queryFormItems | 筛选表单项配置 | TableQueryFormItemProps[] | - | - | - |
queryFormRowProps | 筛选表单行配置 | RowProps | - | - | * |
queryFormColProps | 筛选表单列配置 | ColProps | - | - | * |
queryFormFlexProps | 筛选表单外层 flex 容器配置 | FlexProps | - | - | * |
queryFormSubmitBtn | 筛选表单提交按钮 | boolean / (form: TableQueryFormInstance) => VNode | - | - | * |
queryFormSubmitBtnProps | 筛选表单提交按钮 的 Props | false/OwnBtnProps | - | - | * |
queryFormResetBtn | 筛选表单重置按钮 | boolean / (form: TableQueryFormInstance) => VNode | - | - | * |
queryFormResetBtnProps | 筛选表单重置按钮 的 Props | false/OwnBtnProps | - | - | * |
queryFormOperationBtnsLayout | 筛选表单操作按钮布局方式 | 'fixRight' / 'followLast' / 'followLastEnd' 说明 | 'fixRight' | - | * |
queryFormControlFormItemProps | 配置筛选表单放置操作按钮的 FormItem | FormItemProps | - | - | * |
queryFormItemsControlProps | 统一配置筛选表单控件的 props | object | - | - | * |
queryFormSubmitWithReset | 筛选表单点击重置触发提交 | boolean | false | - | * |
queryFormTimeFormat | 筛选表单 时间参数提交时的格式 | string | 'YYYY-MM-DD HH:mm:ss' | - | * |
cuFormProps | 新增/编辑表单配置项 | FormProps | - | - | * |
cuFormRules | 新增/编辑表单 校验规则 | RuleObject[] | - | - | - |
cuFormDefaultValues | 新增/编辑表单 默认值 | object | - | - | - |
cuFormModalProps | 新增/编辑表单 Modal 配置项 | ModalProps | { width:'65%', destroyOnClose:true } | - | * |
cuFormRowProps | 新增/编辑表单 Row 配置 | RowProps | - | - | * |
cuFormColProps | 新增/编辑表单 Col 配置 | ColProps | - | - | * |
cuFormBackFillByGetDetail | 编辑表单回填内容通过 apis.details 获取,否则使用表中当前行数据 | boolean | true | - | * |
detailModalProps | 详情 Modal 配置项 | ModalProps | - | - | * |
detailDescProps | 详情描述列表配置项 | DescriptionsProps | - | - | * |
detailDescItemProps | 详情描述列表 Item 配置项 | TableDescItemsProps | - | - | * |
detailDescItemEmptyText | 详情描述项值为空值显示的内容 | VNode /string | '-' | - | * |
detailDescItemTimeFormat | 详情描述项值为日期类型时显示的格式 | string | 'YYYY-MM-DD HH:mm:ss' | - | * |
detailBackFillByGetDetail | 详情内容通过 apis.details 获取,否则使用表中当前行数据 | boolean | true | - | * |
ciesBtns | 显示内置表格操作按钮组 | boolean | true | - | * |
ciesBtnsInQueryForm | 内置表格操作按钮组显示在筛选表单中 | boolean | false | - | * |
createBtn | 新增按钮 | false/OwnBtnProps | - | - | * |
importBtn | 导入按钮 | false/OwnBtnProps | - | - | * |
importUploadProps | 导入上传按钮的 props | UploadProps | - | - | * |
importFileParamsFormatter | 导入文件参数处理函数 | (options: UploadRequestOption) =>Promise<any> | - | - | * |
exportDropdown | 下拉导出按钮 | false/OwnDropProps | - | - | * |
exportAllBtn | 导出全部按钮 | false/OwnBtnProps | - | - | * |
exportBtnMode | 导出按钮模式 'dropdown'显示为下拉按钮,'all'时只显示导出全部按钮 | 'dropdown' / 'all' | 'dropdown' | - | * |
exportCurrentPageBtn | 导出当前页 | false/OwnBtnProps | - | - | * |
exportFileByParams | 导出数据通过筛选表单参数 | boolean | false | - | * |
exportFileParamsFormatter | 导出数据时的参数处理函数 | (vals?: any, type?: "currentPage" / "allPage") => Promise<any> | 'page' | - | * |
exportFileName | 导出数据的文件名称 | string | dayjs().valueOf() | - | - |
downloadTemplateBtn | 下载模板按钮 | false/OwnBtnProps | - | - | * |
templateFileName | 模板文件名 | string | dayjs().valueOf() | - | - |
downloadTempalteParamsFormatter | 下载模板的参数处理函数 | ( params:object)=>Promise<object> | - | - | * |
requestParamsFormatter | 列表数据请求参数最终处理函数 | ( params:object)=>Promise<object> | - | - | * |
value(v-model) | 表格双向绑定的数据,内部请求的时也能通过该属性在外部获取操作,用于可编辑表格 | Ref<DataItem[]> | - | - | - |
TableColumnProps
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
... | 继承 antd-vue ColumnProps | - | - | |
hidden | 隐藏列 | boolean | - | |
type | 内容类型 可选 序号/操作/时间/数字 | 'index' / 'control' / 'date' / 'number' | - | |
nowrap | 列头不换行 | boolean | - | |
emptyText | 值为空时显示的内容 | VNode / string | - | |
timeFormat | type 为'date'时,显示的时间格式 | string | - | |
numberFormat | type 为'number'时,显示的数字格式 | Numeral.format / (val:Numeral,local: string/number) => string / number / VNode | '0[.]00' | |
numberComputed | type 为'number'时用于数字运算,返回结果将回填至 numeral 进行格式化。当 numberFormat 为函数时,该属性不生效 | (val:Big.Big,Big: Big) => number | - | |
formItemProps | 列对应到 cuForm(新增/编辑表单) 中的表单项 配置项 | object | - | |
descItemProps | 列对应到 detailDesc(详情描述列表) 中的描述项 配置项 | object | - | |
editable | 是否可编辑 | boolean | - | |
editControl | 控件类型 | ControlMapType | - | |
editControlProps | 控件的 props | object | - |
formItemProps
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
... | 继承 antd-vue FormItemProps | - | - | |
name | 表单域 model 字段 | string | - | |
control | 控件类型 | ControlMapType | ControlMapType.Input | |
controlProps | 控件 Props | object | - | |
colProps | 所在列的配置 | ColProps | - | |
sort | 显示位置的排序 | number | - | |
customControl | 自定义控件,返回一个控件,绑定 model 对应值即可 | (options,model: 表单绑定的 model) => VNode / JSX.Element | - | |
customRender | 自定义渲染,可用于自定义多个收集项,收集项需要用 FormItem 包裹 | (model: Reactive<any>, form: FormInstance) => VNode / JSX.Element | - |
descItemProps
参数 | 说明 | 类型 | 必填 |
---|---|---|---|
... | 继承 antd-vue DescItemProps | ||
hidden | 是否隐藏 | boolean | |
render | 自定义渲染 | (_: any, record: any, column: TableColumnProps, index: number) => VNode / JSX.Element |
autoRequest
注意
- autoRequest 配置项同步 vue watch 的 Options,详见Vue-Watch;
- autoRequest 为 false 时将不创建 watch, 意味着将不自动发起请求
参数 | 说明 | 类型 | 默认值 | 版本 | 必填 |
---|---|---|---|---|---|
immediate | 立即执行 | boolean | true | - | |
deep | 强制深度遍历 resParams,以便在深层级变更时触发回调 | boolean | - | - | |
flush | 调整回调函数的刷新时机 | boolean | - | - | |
onTrack / onTrigger | 调试侦听器的依赖 | boolean | - | - | |
once | 请求只会运行一次,首次运行后自动停止。 | boolean | - | - |
apis
参数 | 说明 | 类型 | 默认值 | 版本 | 必填 |
---|---|---|---|---|---|
list | 获取数据列表 | (params?:any,config?:AxiosRequestConfig) => Promise<AxioResponse> | - | - | |
details | 获取单行详情数据 | (data?:any,config?:AxiosRequestConfig) => Promise<AxioResponse> | - | - | |
create | 新增数据 | (data?:any,config?:AxiosRequestConfig) => Promise<AxioResponse> | - | - | |
update | 更新数据 | (data?:any,config?:AxiosRequestConfig) => Promise<AxioResponse> | - | - | |
delete | 删除单行数据 | (params?:any,config?:AxiosRequestConfig) => Promise<AxioResponse> | - | - | |
export | 导出数据, api 需设置 responseType: 'blob' | (params?:any,config?:AxiosRequestConfig) => Promise<AxioResponse> | - | - | |
import | 导入数据, api 需设置 'content-type': 'multipart/form-data' | (data?:any,config?:AxiosRequestConfig) => Promise<AxioResponse> | - | - | |
template | 导出数据模板, api 需设置 responseType: 'blob' | (params?:any,config?:AxiosRequestConfig) => Promise<AxioResponse> | - | - |
fieldsNames
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
page | 页码 (调用 apis.list 时参数中的 page ) | string | 'page' | * |
pageSize | 每页条目数 (调用 apis.list 时参数中的 pageSize ) | string | 'pageSize' | * |
total | 调用 apis.list 后拿取数据总数的字段 | string / string[] | 'total' | * |
list | 调用 apis.list 后拿取数据列表的字段 | string / string[] | 'list' | * |
details | 调用 apis.details 后拿取数据的字段 | string / string[] | 'data' | * |
export | 调用 apis.export 后拿取数据的字段 | string / string[] | 'data' | * |
template | 调用 apis.template 后拿取数据的字段 | string / string[] | 'data' | * |
editCellTempKey | 可编辑单元格绑定值所属的 key,默认取行数据的'id' | string | 'id' | * |
controlColumnBtns
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
detail | 详情按钮 | false / ButtonProps & { children?: VNode / string } | |
edit | 编辑按钮 | false / ButtonProps & { children?: VNode / string } | |
delete | 删除按钮 | false / ButtonProps & { children?: VNode / string } |
TableQueryFormItemProps
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
... | 继承 antd-vue FormItemProps | - | - | |
control | 控件类型 | ControlMapType | ControlMapType.Input | |
controlProps | 控件 Props | object | - | |
colProps | 所在列的配置 | ColProps | - | |
customControl | 自定义控件,返回一个控件,绑定 model 对应值即可 | (model: 表单域绑定的 model, name:string, realName: string) => VNode | - |
QueryFormOperationBtnsLayout
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
fixRight | 固定在右侧。 表单项和操作按钮呈左右布局 | - | √ |
followLast | 跟随最后一个表单项 | - | - |
followLastEnd | 跟随最后一个表单项并在剩余空间的末尾 | - | - |
TableQueryFormInstance
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
... | 继承 antd-vue 的 FormInstance | |||
submit | 提交方法 | (vals: any) => void | ||
reset | 重置方法 | () => void |
OwnBtnProps
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
... | 继承 antd-vue ButtonProps | |||
children | Button 的子节点 | JSX.Element[] / VNode[] / string | ||
class | - | string | ||
style | - | CSSStyleSheet |
OwnPopoverProps
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
... | 继承 antd-vue PopoverProps | |||
children | Button 的子节点 | JSX.Element[] / VNode[] / string | ||
class | - | string | ||
style | - | CSSStyleSheet | ||
buttonProps | 气泡按钮的 props | ButtonProps |
OwnDropProps
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
... | 继承 antd-vue DropdownProps | |||
children | Button 的子节点 | JSX.Element[] / VNode[] / string | ||
class | - | string | ||
style | - | CSSStyleSheet | ||
buttonProps | 下拉按钮的 props | ButtonProps |
TableDescItemsProps
参数 | 说明 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
... | 继承 antd-vue ButtonProps | |||
children | Button 的子节点 | JSX.Element[] / VNode[] / string | ||
class | - | string | ||
style | - | CSSStyleSheet |
ControlMapType
目前支持的控件类型
Input | InputNumber | Select | DatePicker | RangePicker | Checkbox | CheckboxGroup | Radio | RadioGroup | TextArea
scroll
参数 | 说明 | 类型 | 默认值 | 版本 | global |
---|---|---|---|---|---|
scrollToFirstRowOnChange | 当分页、排序、筛选变化后是否滚动到表格顶部 | boolean | true | - | * |
x | 设置横向滚动,也可用于指定滚动区域的宽, 可以设置为像素值,百分比,'auto',true 和 'max-content' | string / number / 'max-content' | 'max-content' | - | * |
y | 设置纵向滚动,也可用于指定滚动区域的高,可以设置为像素值。 值为'auto'时将自动计算高度, 注意 Table 的父容器需有高度或者为 flex 容器 | string / number / 'auto' | 'auto' | - | * |
autoSizeConfig
参数 | 说明 | 类型 | 默认值 | 版本 | global |
---|---|---|---|---|---|
wait | 延迟执行的毫秒数 | number | 300 | - | - |
options | 一个选项对象 | object | - | - | - |
-signal | AbortSignal 对象,用于取消防抖函数的执行 | AbortSignal | - | - | - |
-edges | 一个数组,指定函数应在何时被调用 | Array<'leading' \ 'trailing'> | ['trailing'] | - | - |
——'leading' | 如果包含,函数将在第一次调用时立即执行 | - | - | - | - |
——'trailing' | 如果包含,函数将在距离上次调用 wait 毫秒后执行 | - | - | - | - |
tableTextConfig
参数 | 说明 | 类型 | 默认值 | 版本 | global |
---|---|---|---|---|---|
modalTitle | modal 框的 title | object | - | - | * |
-create | 新增 modal | string | '新增' | - | * |
-update | 编辑 modal | string | '编辑' | - | * |
-details | 详情 modal | string | '详情' | - | * |
-create | 新增 modal | string | '新增' | - | * |
message | message 的内容 | object | - | - | * |
-createSuccess | - | string | '新增成功!' | - | * |
-createError | - | string | '新增失败!' | - | * |
-updateSuccess | - | string | '编辑成功!' | - | * |
-updateError | - | string | '编辑失败!' | - | * |
-deleteSuccess | - | string | '删除成功!' | - | * |
-deleteError | - | string | '删除失败!' | - | * |
-exportSuccess | - | string | '导出成功!' | - | * |
-exportError | - | string | '导出失败!' | - | * |
-importSuccess | - | string | '导入成功!' | - | * |
-importError | - | string | '导入失败!' | - | * |
-downloadTemplateSuccess | - | string | '模板下载成功!' | - | * |
-downloadTemplateError | - | string | '模板下载失败!' | - | * |
ownPaginProps
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
showSizeChanger | - | boolean | true |
showTotal | - | function | (total) => `共${total}条数据` |
showQuickJumper | - | boolean | true |
defaultPageSize | - | number | 10 |
Event
参数 | 说明 | 类型 | 默认值 | 版本 | global |
---|---|---|---|---|---|
onBeforeRequestSource | 请求列表数据前触发,返回 false 时不请求 | (params: object) => Promise<any/boolean> | - | - | - |
onSourceSuccess | 列表数据请求成功触发,用于处理填入列表的数据 需匹配 fieldsNames.total;fieldsNames.list | (res: AxiosResponse) =>Promise<object> | - | - | * |
onSourceError | 列表数据请求失败触发 | (err: Error) => void | - | - | * |
onBeforeRequestDetails | 获取单行详情数据前触发,用于处理获取单行详情的参数 | ( params:object)=>Promise<object> | - | - | * |
onGetRowDetail | 成功获取单行详情数据触发,用于设置填入编辑表单/详情 的数据源 | (res: AxiosResponse) => Promise<object> | - | - | * |
onBeforeRowEditBackFill | 点编辑,回填表单内容前触发,用于处理回填进编辑表单的数据 | (res: AxiosResponse, record?: any ) => Promise<object> | - | - | * |
onBeforeCuFormSubmit | 新增/编辑表单提交前触发,用于修改将提交的表单数据,返回 false 则不发起请求 | (vals: object,metaValues?: any)=> Promise<object/false> | - | - | * |
onCuFormSubmitSuccess | 新增/编辑成功触发,返回 false 则中断内置的 message | (res: AxiosResponse, cuModalFormIsEdit: boolean, {cancelCUModalForm : () => void}) => boolean/void | - | - | * |
onCuFormSubmitError | 新增/编辑失败触发,返回 false 则中断内置的 message | (res: Error, cuModalFormIsEdit: boolean,{cancelCUModalForm : () => void}) => false/void | - | - | * |
onCuFormCancel | 新增/编辑 Modal onCancel 时触发,返回 false 则不关闭 | () => boolean / void | - | - | - |
onBeforeRowDelete | 删除单行数据前触发,用于处理调用 apis.delete 的参数 | (vals: object,metaValues?: any)=> Promise<object/false> | - | - | * |
onRowDeleteSuccess | 删除成功触发,返回 false 则中断内置的 message | (res: AxiosResponse, info?: any) => boolean / void | - | - | * |
onRowDeleteError | 删除失败触发,返回 false 则中断内置的 message | (err: Error) => false / void | - | - | * |
onExportRequestSuccess | apis.export 调用成功触发,用于处理返回结果,返回 false 则需自定义下载逻辑 | (res: AxiosResponse) => Promise<DownloadResResponse/false> | - | - | * |
onExportSuccess | 导出成功触发,返回 false 则中断内置的 message | (downloadRes:JsDownloadFile) => Promise<boolean / void> | - | - | * |
onExportError | 导出失败触发,返回 false 则中断内置的 message | (err: Error) => Promise<boolean / void> | - | - | * |
onImportSuccess | 导入成功触发,返回 false 则中断内置的 message | (res: AxiosResponse) => Promise<void / boolean> | - | - | * |
onImportError | 导入失败触发,返回 false 则中断内置的 message | (err: Error) => Promise<boolean / void> | - | - | * |
onTemplateRequestSuccess | apis.template 调用成功触发,用于处理返回结果,返回 false 则需自定义下载逻辑 | (res: AxiosResponse) => Promise<DownloadResResponse / false> | - | - | * |
onTemplateDownloadSuccess | 模板下载成功触发,返回 false 则中断内置的 message | (downloadRes:JsDownloadFile) => Promise<boolean / void> | - | - | * |
onTemplateDownloadError | 模板下载失败触发,返回 false 则中断内置的 message | (err: Error) => Promise<boolean / void> | - | - | * |
onCellEditConfirm | 编辑单元格,点击确定时触发,返回 false 则中断内置回填逻辑,需自定义 | (info: CellEditConfirmInfo ,editData: UnwrapRef<Reactive<Record<string, DataItem>>>) => Promise<boolean/ void> | - | - | - |
DownloadResResponse
参数 | 说明 | 类型 | 必填 |
---|---|---|---|
thumbUrl | 下载地址 | string | * |
filename | 文件名 | string | |
config | js-file-downloader 的配置项 | object |
CellEditConfirmInfo
参数 | 说明 | 类型 | 必填 |
---|---|---|---|
name | 字段名 | string / string[] | |
dataIndex | TableColumnProps['dataIndex'] | string / string[] | |
handlePath | 实际操作的字段路径 | string | |
record | 当前行的数据 | DataItem | |
value | 控件输入的值 | any | |
closeCellEdit | 关闭编辑的方法 | () => void |
Slot
参数 | 说明 | 类型 |
---|---|---|
... | 继承 antd-vue-table 原本的 slot | |
customCiesBtns | 自定义表格按钮 新增/导入/导出/下载模板/列配置 | v-slot:customCiesBtns="customCiesBtnsOpt" |
customControlColumnBtns | 自定义操作列内容 | v-slot:customControlColumnBtns="customControlColumnBtnsOpt" |
customQueryFormBtns | 自定义筛选表单的按钮组 | v-slot:customQueryFormBtns="customQueryFormBtnsOpt |
customCiesBtnsOpt
ts
interface customCiesBtnsOpt {
CreateBtn: VNode // 新增按钮
ImportBtn: VNode // 导入按钮
ExportDropDown: VNode // 下拉导出按钮 (包含导出当前页/全部页 按钮)
ExportCurrentPageBtn: VNode // 导出当前页按钮
ExportAllBtn: VNode // 导出全部按钮
ColumnSettingBtn: VNode // 列配置按钮
DownloadTemplateBtn: VNode // 下载模板按钮
}
customControlColumnBtnsOpt
ts
interface customControlColumnBtnsOpt {
DetailBtn: VNode // 详情按钮
EditBtn: VNode // 编辑按钮
DeleteBtn: VNode // 删除按钮
deleteRow: (params: any) => Promise<void> // 删除当前行,自定义删除按钮时 @click绑定这个方法,需传入params供apis.delete请求使用
editRow: (params: any) => Promise<void> // 编辑当前行,自定义编辑按钮时 @click绑定这个方法,需传入params供apis.update请求使用
openRowDetails: (params: any) => Promise<void> // 打开当前行的详情modal,自定义编辑按钮时 @click绑定这个方法,需传入params供apis.details请求使用
rowInfo: obj // 当前行/列的信息
metaColumnInfo: TableColumnProps // 当前行列的源配置信息
}
customQueryFormBtnsOpt
ts
interface customQueryFormBtnsOpt {
CreateBtn: VNode // 新增按钮
ImportBtn: VNode // 导入按钮
ExportDropDown: VNode // 下拉导出按钮 (包含导出当前页/全部页 按钮)
ExportCurrentPageBtn: VNode // 导出当前页按钮
ExportAllBtn: VNode // 导出全部按钮
ColumnSettingBtn: VNode // 列配置按钮
DownloadTemplateBtn: VNode // 下载模板按钮
SubmitBtn: VNode // 提交按钮
ResetBtn: VNode // 重置按钮
QueryFormInstance: VNode // 筛选表单的实例对象
}
TableInstance
ts
interface TableInstance {
source: any[] // 通过api或者dataSource属性传入的数据列表
updateSource: () => Promise<void> // 更新数据列表的方法
QueryForm: () => JSX.Element | VNode // 查询表单组件
queryFormModel: Reactive<{ values: any }> // 查询表单绑定的数据
QueryFormInstance: Partial<TableQueryFormInstance> // 查询表单实例
Pagination: () => JSX.Element | VNode // 内置分页器组件
cuModalFormIsEdit: Ref<boolean> // 新增/编辑表单 当前是否为编辑模式 ,false为新增模式
cuFormModel: Reactive<{ values: any }> // 新增/编辑表单绑定的数据
CreateBtn: (props?: OwnBtnProps) => JSX.Element | VNode // 新增按钮
ImportBtn: (props?: OwnBtnProps) => JSX.Element | VNode // 导入按钮
ExportDropDown: (props?: OwnDropProps) => JSX.Element | VNode // 导出数据下拉菜单
ExportCurrentPageBtn: (props?: OwnBtnProps) => JSX.Element | VNode // 导出当前页数据按钮
ExportAllBtn: (props?: OwnBtnProps) => JSX.Element | VNode // 导出全部数据按钮
ColumnSettingBtn: (props?: OwnBtnProps) => JSX.Element | VNode // 列头控件按钮
DownloadTemplateBtn: (props?: OwnBtnProps) => JSX.Element | VNode // 下载模板按钮
onResize: (entries?: any) => void // 重新计算scroll.y值
}
默认全局配置
table.tsx
tsx
import { TableProps } from '@src/components'
import {
CloudDownloadOutlined,
ExportOutlined,
ImportOutlined,
PlusOutlined,
SearchOutlined,
SettingOutlined,
UndoOutlined,
} from '@ant-design/icons-vue'
export const TableConfig: TableProps = {
showSorterTooltip: true,
full: false,
autoRequest: {
immediate: true,
},
scroll: {
x: 'max-content',
y: 'auto',
scrollToFirstRowOnChange: true,
},
tableLayout: 'fixed',
fieldsNames: {
page: 'page',
pageSize: 'pageSize',
total: 'total',
list: 'list',
details: 'data',
export: 'data',
template: 'data',
editCellTempKey: 'id',
},
onSourceSuccess: null,
onSourceError: null,
onBeforeRowEditBackFill: null,
onGetRowDetail: null,
onBeforeCuFormSubmit: null,
onCuFormSubmitSuccess: null,
onCuFormSubmitError: null,
onBeforeRowDelete: null,
onRowDeleteSuccess: null,
onRowDeleteError: null,
onExportRequestSuccess: null,
onExportSuccess: null,
onExportError: null,
importFileParamsFormatter: null,
exportFileParamsFormatter: null,
onImportSuccess: null,
onImportError: null,
downloadTempalteParamsFormatter: null,
onTemplateRequestSuccess: null,
onTemplateDownloadSuccess: null,
onTemplateDownloadError: null,
showOwnPager: true,
ownPagin: true,
ownPaginProps: {
showSizeChanger: true,
showTotal: (total) => `共${total}条数据`,
showQuickJumper: true,
defaultPageSize: 10,
},
queryForm: true,
queryFormProps: null,
queryFormSubmitWithReset: false,
queryFormRowProps: null,
queryFormColProps: null,
queryFormFlexProps: null,
queryFormSubmitBtn: true,
queryFormResetBtn: true,
queryFormTimeFormat: 'YYYY-MM-DD HH:mm:ss',
queryFormSubmitBtnProps: {
type: 'primary',
children: '查询',
icon: <SearchOutlined />,
},
queryFormResetBtnProps: {
children: '重置',
icon: <UndoOutlined />,
},
queryFormOperationBtnsLayout: 'fixRight',
queryFormControlFormItemProps: {
class: '',
},
queryFormItemsControlProps: null,
indexColumn: true,
indexColumnWidth: 80,
indexColumnProps: {},
controlColumn: true,
controlColumnWidth: 220,
controlColumnWidthProps: {},
columnsAlign: 'left',
columnsEllipsis: true,
columnsSorter: true,
columnsTitleNoWrap: true,
columnsTimeFormat: 'YYYY-MM-DD HH:mm:ss',
columnsEmptyText: '-',
controlColumnBtns: {
detail: {
type: 'link',
children: '详情',
},
edit: {
type: 'link',
children: '编辑',
},
delete: {
type: 'link',
danger: true,
children: '删除',
},
},
cuFormProps: {
labelCol: {
span: 10,
},
},
cuFormRules: null,
cuFormModalProps: {
width: '65%',
destroyOnClose: true,
},
cuFormRowProps: null,
cuFormColProps: {
span: 8,
},
cuFormBackFillByGetDetail: true,
tableTextConfig: {
modalTitle: {
create: '新增',
update: '编辑',
details: '详情',
},
message: {
createSuccess: '新增成功!',
createError: '新增失败!',
updateSuccess: '编辑成功!',
updateError: '编辑失败!',
deleteSuccess: '删除成功!',
deleteError: '删除失败!',
exportSuccess: '导出成功!',
exportError: '导出失败!',
importSuccess: '导入成功!',
importError: '导入失败!',
downloadTemplateSuccess: '模板下载成功!',
downloadTemplateError: '模板下载失败!',
},
},
detailBackFillByGetDetail: true,
detailDescItemEmptyText: '-',
detailDescItemProps: null,
detailDescItemTimeFormat: 'YYYY-MM-DD HH:mm:ss',
detailModalProps: {},
detailDescProps: {},
ciesBtns: true,
ciesBtnsInQueryForm: false,
createBtn: {
children: '新增',
icon: <PlusOutlined />,
},
importBtn: {
children: '导入',
icon: <ImportOutlined />,
},
exportBtnMode: 'dropdown',
exportDropdown: {
children: '导出',
buttonProps: {
icon: <ExportOutlined />,
},
},
exportCurrentPageBtn: {
children: '导出当前页',
},
exportAllBtn: {
children: '导出全部',
},
downloadTemplateBtn: {
children: '下载模板',
icon: <CloudDownloadOutlined />,
},
columnSettingBtn: {
children: '',
buttonProps: {
title: '列配置',
icon: <SettingOutlined />,
},
},
exportFileByParams: false,
importUploadProps: null,
autoSizeConfig: null,
minScollHeight: 50,
}