Skip to content

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表格是否撑满容器booleanfalse-*
scroll表格是否可滚动,也可以指定滚动区域的宽、高 配置项object--*
autoSizeConfig表格自动计算高度函数防抖配置 配置项object--*
minScollHeight指定自动计算表格 scroll.y 值的最小高度, scroll.y 指定为 number 时该值不生效number50-*
autoRequest指定表格自动请求列表数据配置 配置项false / object--*
autoRequestDependencies自定义表格自动请求列表数的依赖项({params,apis}) => WatchSource--*
apis提供给表格内置请求的 api 配置项object---
fieldsNames配置表格调用 api 后从返回结果中拿取数据的字段 配置项object--*
tableTextConfig配置表格内置提示的文本 配置项object--*
params请求时额外添加的参数object---
columns表格列配置TableColumnProps[]---
columnsTitleNoWrap统一列头不换行booleantrue-*
columnsAlign统一列对齐方式'left' / 'center' / 'right''left'-*
columnsSorter统一列排序配置, 除['index','control']列,其他列均内置了排序逻辑ColumnProps['sorter']true-*
columnsEllipsis统一列的 ellipsis 属性booleantrue-*
columnsTimeFormat当 column.type == 'date'时,处理时间显示的格式string'YYYY-MM-DD HH:mm:ss'-*
columnsEmptyText统一列取值为空时显示的内容VNode / string'-'-*
indexColumn开启序号列booleantrue-*
indexColumnWidth序号列宽度number80-*
indexColumnProps序号列 PropsTableColumnProps--*
controlColumn开启操作列booleantrue-*
controlColumnWidth操作列宽度number220-*
controlColumnWidthProps操作列 PropsTableColumnProps--*
controlColumnBtns操作列按钮配置项controlColumnBtns--*
columnSettingBtn列配置按钮false / OwnPopoverPropstrue-*
showOwnPager显示内置分页器booleantrue-*
ownPagin开启内置分页,值为 false 时请求数据参数将不加入分页参数booleantrue-*
ownPaginProps内置分页器 PropspaginationPropsobject-*
queryForm显示筛选表单booleantrue-*
queryFormDefaultValues筛选表单默认值object---
queryFormProps筛选表单的 PropsFormProps--*
queryFormItems筛选表单项配置TableQueryFormItemProps[]---
queryFormRowProps筛选表单行配置RowProps--*
queryFormColProps筛选表单列配置ColProps--*
queryFormFlexProps筛选表单外层 flex 容器配置FlexProps--*
queryFormSubmitBtn筛选表单提交按钮boolean / (form: TableQueryFormInstance) => VNode--*
queryFormSubmitBtnProps筛选表单提交按钮 的 Propsfalse/OwnBtnProps--*
queryFormResetBtn筛选表单重置按钮boolean / (form: TableQueryFormInstance) => VNode--*
queryFormResetBtnProps筛选表单重置按钮 的 Propsfalse/OwnBtnProps--*
queryFormOperationBtnsLayout筛选表单操作按钮布局方式'fixRight' / 'followLast' / 'followLastEnd' 说明'fixRight'-*
queryFormControlFormItemProps配置筛选表单放置操作按钮的 FormItemFormItemProps--*
queryFormItemsControlProps统一配置筛选表单控件的 propsobject--*
queryFormSubmitWithReset筛选表单点击重置触发提交booleanfalse-*
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 获取,否则使用表中当前行数据booleantrue-*
detailModalProps详情 Modal 配置项ModalProps--*
detailDescProps详情描述列表配置项DescriptionsProps--*
detailDescItemProps详情描述列表 Item 配置项TableDescItemsProps--*
detailDescItemEmptyText详情描述项值为空值显示的内容VNode /string'-'-*
detailDescItemTimeFormat详情描述项值为日期类型时显示的格式string'YYYY-MM-DD HH:mm:ss'-*
detailBackFillByGetDetail详情内容通过 apis.details 获取,否则使用表中当前行数据booleantrue-*
ciesBtns显示内置表格操作按钮组booleantrue-*
ciesBtnsInQueryForm内置表格操作按钮组显示在筛选表单中booleanfalse-*
createBtn新增按钮false/OwnBtnProps--*
importBtn导入按钮false/OwnBtnProps--*
importUploadProps导入上传按钮的 propsUploadProps--*
importFileParamsFormatter导入文件参数处理函数(options: UploadRequestOption) =>Promise<any>--*
exportDropdown下拉导出按钮false/OwnDropProps--*
exportAllBtn导出全部按钮false/OwnBtnProps--*
exportBtnMode导出按钮模式 'dropdown'显示为下拉按钮,'all'时只显示导出全部按钮'dropdown' / 'all''dropdown'-*
exportCurrentPageBtn导出当前页false/OwnBtnProps--*
exportFileByParams导出数据通过筛选表单参数booleanfalse-*
exportFileParamsFormatter导出数据时的参数处理函数(vals?: any, type?: "currentPage" / "allPage") => Promise<any>'page'-*
exportFileName导出数据的文件名称stringdayjs().valueOf()--
downloadTemplateBtn下载模板按钮false/OwnBtnProps--*
templateFileName模板文件名stringdayjs().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-
timeFormattype 为'date'时,显示的时间格式string-
numberFormattype 为'number'时,显示的数字格式Numeral.format / (val:Numeral,local: string/number) => string / number / VNode'0[.]00'
numberComputedtype 为'number'时用于数字运算,返回结果将回填至 numeral 进行格式化。当 numberFormat 为函数时,该属性不生效(val:Big.Big,Big: Big) => number-
formItemProps列对应到 cuForm(新增/编辑表单) 中的表单项 配置项object-
descItemProps列对应到 detailDesc(详情描述列表) 中的描述项 配置项object-
editable是否可编辑boolean-
editControl控件类型ControlMapType-
editControlProps控件的 propsobject-

formItemProps

参数说明类型默认值必填
...继承 antd-vue FormItemProps--
name表单域 model 字段string-
control控件类型ControlMapTypeControlMapType.Input
controlProps控件 Propsobject-
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立即执行booleantrue-
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控件类型ControlMapTypeControlMapType.Input
controlProps控件 Propsobject-
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
childrenButton 的子节点JSX.Element[] / VNode[] / string
class-string
style-CSSStyleSheet

OwnPopoverProps

参数说明类型默认值必填
...继承 antd-vue PopoverProps
childrenButton 的子节点JSX.Element[] / VNode[] / string
class-string
style-CSSStyleSheet
buttonProps气泡按钮的 propsButtonProps

OwnDropProps

参数说明类型默认值必填
...继承 antd-vue DropdownProps
childrenButton 的子节点JSX.Element[] / VNode[] / string
class-string
style-CSSStyleSheet
buttonProps下拉按钮的 propsButtonProps

TableDescItemsProps

参数说明类型默认值必填
...继承 antd-vue ButtonProps
childrenButton 的子节点JSX.Element[] / VNode[] / string
class-string
style-CSSStyleSheet

ControlMapType

目前支持的控件类型

Input | InputNumber | Select | DatePicker | RangePicker | Checkbox | CheckboxGroup | Radio | RadioGroup | TextArea

scroll

参数说明类型默认值版本global
scrollToFirstRowOnChange当分页、排序、筛选变化后是否滚动到表格顶部booleantrue-*
x设置横向滚动,也可用于指定滚动区域的宽,
可以设置为像素值,百分比,'auto',true 和 'max-content'
string / number / 'max-content''max-content'-*
y设置纵向滚动,也可用于指定滚动区域的高,可以设置为像素值。
值为'auto'时将自动计算高度,
注意 Table 的父容器需有高度或者为 flex 容器
string / number / 'auto''auto'-*

autoSizeConfig

参数说明类型默认值版本global
wait延迟执行的毫秒数number300--
options一个选项对象object---
-signalAbortSignal 对象,用于取消防抖函数的执行AbortSignal---
-edges一个数组,指定函数应在何时被调用Array<'leading' \ 'trailing'>['trailing']--
——'leading'如果包含,函数将在第一次调用时立即执行----
——'trailing'如果包含,函数将在距离上次调用 wait 毫秒后执行----

tableTextConfig

参数说明类型默认值版本global
modalTitlemodal 框的 titleobject--*
-create新增 modalstring'新增'-*
-update编辑 modalstring'编辑'-*
-details详情 modalstring'详情'-*
-create新增 modalstring'新增'-*
messagemessage 的内容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-booleantrue
showTotal-function(total) => `共${total}条数据`
showQuickJumper-booleantrue
defaultPageSize-number10

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--*
onExportRequestSuccessapis.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>--*
onTemplateRequestSuccessapis.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
configjs-file-downloader 的配置项object

CellEditConfirmInfo

参数说明类型必填
name字段名string / string[]
dataIndexTableColumnProps['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,
}