GapTable
使用 antdesign Table 二次封装的基础表格组件
说明
- 表格列存在 control_type 属性时,若需要气泡卡片,需将内容通过 slot 插槽传入,组件内部无默认值,不传则显示空
- 多选或树形结构数据时 rowkey 必传且唯一
基本用法

示例
vue
<template>
<div id="app">
<a-button @click="clearCheckData">清空选中项</a-button>
<GapTable
ref="tableRef"
:columns="tableColumns"
:dataSource="dataSource"
@page-change="pageChange"
@operate="handleOperate"
:config-data="configData"
@handleSelection="handleSelection"
:unit-config="{ defaultVal: Units.tenThousand }"
@on-expand="onExpand"
>
<template #customEllipsis="{ column, record }">
<div v-if="column.dataIndex == 'forewarning'">
{{ record.forewarning == 3 ? '超期' : record.forewarning == 1 ? '待付' : '正常' }}
</div>
</template>
<template #expandedRowRender="{ record, index, indent, expanded }">
<p>{{ record }}{{ index }}</p>
<p>indent{{ indent }}</p>
<p>expanded{{ expanded }}</p>
</template>
</GapTable>
</div>
</template>
<script lang="ts" setup>
import { ref, h } from 'vue'
import { AlertFilled } from '@ant-design/icons-vue'
// 引用组件
import { GapTable } from 'ctj-ui-next'
import {
ControlType,
tableViewConfig,
pageConfig,
DataItem,
columnItem,
opeColumnItem,
configData,
Units,
} from 'ctj-ui-next/lib/index'
const tableRef = ref()
const tableColumns = ref<columnItem[]>([
{
title: '指标名称',
dataIndex: 'monetaryAll',
key: 'monetaryAll',
width: 200,
configs: {
disabled: false,
},
},
{
title: '测试自定义列',
customEllipsis: true,
control_type: ControlType.render,
dataIndex: 'forewarning',
key: 'forewarning',
width: 200,
configs: {
cusRender: (record: any) => {
const level = record.forewarning || 0
const levelColor: any = {
1: '#faad14',
2: '#52c41a',
3: '#ff4d4f',
}
return h(AlertFilled, {
style: 'font-size:20px;color:' + (levelColor[level] || '#52c41a'),
})
},
},
},
{
title: '收款人',
dataIndex: 'payee_user_name',
key: 'payee_user_name',
width: 150,
control_type: ControlType.input,
configs: {
disabled: false,
},
},
{
title: '操作',
dataIndex: 'operation',
key: 'operation',
control_type: ControlType.operation,
operateConfigs: {
delete: {
disabledCondition: (record: any) => {
if (record.status == 0) {
return true
} else {
return false
}
},
},
cancel: {
disabledCondition: (record: any) => {
if (record.status == 1) {
return true
} else {
return false
}
},
},
punish: {
disabledCondition: (record: any) => {
if (record.status == 0) {
return true
} else {
return false
}
},
},
},
opeColums: [
{
type: 'delete',
title: '删除',
key: 'delete',
},
{
type: 'edit',
title: '编辑',
key: 'edit',
},
{
type: 'punish',
title: '发布',
key: 'punish',
},
{
type: 'cancel',
title: '撤销发布',
key: 'cancel',
},
],
},
])
const dataSource = ref<DataItem[]>([
{
forewarning: 0,
id: '1',
status: 0,
pay_money: 34,
},
{
forewarning: 1,
id: '2',
status: 1,
pay_money: 56,
},
{
forewarning: 2,
is: '3',
status: 0,
pay_money: 34,
},
{
forewarning: 3,
id: '4',
status: 1,
pay_money: 34,
},
])
const configData = ref<configData>({
viewConfig: <tableViewConfig>{
rowKey: 'id',
bordered: true,
isHeight: true,
checkType: 'checkbox',
},
cusPagination: <pageConfig>{
current: 1,
pageSize: 20,
total: 4,
},
footerConfig: {
totalSum: {
titleKey: 'monetaryAll',
title: '总计',
data: {
pay_money: 158,
},
},
checkedSum: {
title: '选中合计',
titleKey: 'monetaryAll',
totalKey: ['pay_money'],
},
customFooter: {
titleKey: 'monetaryAll',
title: '收款',
data: {
pay_money: 4400,
},
},
},
})
let selectData: any = ref([])
//页码切换
const pageChange = (page: number, pageSize: number) => {}
//右侧操作列操作按钮
const handleOperate = (code: string, record: DataItem, index: number) => {}
//多选
const handleSelection = (selectedRows: DataItem[]) => {}
//清除选中项
const clearCheckData = () => {
tableRef.value.clearSelected()
}
//表格行展开事件
const onExpand = (expanded: boolean, record: any) => {}
</script>
<style lang="less" scoped>
#app {
padding: 8px;
background-color: #fff;
}
</style><template>
<div id="app">
<a-button @click="clearCheckData">清空选中项</a-button>
<GapTable
ref="tableRef"
:columns="tableColumns"
:dataSource="dataSource"
@page-change="pageChange"
@operate="handleOperate"
:config-data="configData"
@handleSelection="handleSelection"
:unit-config="{ defaultVal: Units.tenThousand }"
@on-expand="onExpand"
>
<template #customEllipsis="{ column, record }">
<div v-if="column.dataIndex == 'forewarning'">
{{ record.forewarning == 3 ? '超期' : record.forewarning == 1 ? '待付' : '正常' }}
</div>
</template>
<template #expandedRowRender="{ record, index, indent, expanded }">
<p>{{ record }}{{ index }}</p>
<p>indent{{ indent }}</p>
<p>expanded{{ expanded }}</p>
</template>
</GapTable>
</div>
</template>
<script lang="ts" setup>
import { ref, h } from 'vue'
import { AlertFilled } from '@ant-design/icons-vue'
// 引用组件
import { GapTable } from 'ctj-ui-next'
import {
ControlType,
tableViewConfig,
pageConfig,
DataItem,
columnItem,
opeColumnItem,
configData,
Units,
} from 'ctj-ui-next/lib/index'
const tableRef = ref()
const tableColumns = ref<columnItem[]>([
{
title: '指标名称',
dataIndex: 'monetaryAll',
key: 'monetaryAll',
width: 200,
configs: {
disabled: false,
},
},
{
title: '测试自定义列',
customEllipsis: true,
control_type: ControlType.render,
dataIndex: 'forewarning',
key: 'forewarning',
width: 200,
configs: {
cusRender: (record: any) => {
const level = record.forewarning || 0
const levelColor: any = {
1: '#faad14',
2: '#52c41a',
3: '#ff4d4f',
}
return h(AlertFilled, {
style: 'font-size:20px;color:' + (levelColor[level] || '#52c41a'),
})
},
},
},
{
title: '收款人',
dataIndex: 'payee_user_name',
key: 'payee_user_name',
width: 150,
control_type: ControlType.input,
configs: {
disabled: false,
},
},
{
title: '操作',
dataIndex: 'operation',
key: 'operation',
control_type: ControlType.operation,
operateConfigs: {
delete: {
disabledCondition: (record: any) => {
if (record.status == 0) {
return true
} else {
return false
}
},
},
cancel: {
disabledCondition: (record: any) => {
if (record.status == 1) {
return true
} else {
return false
}
},
},
punish: {
disabledCondition: (record: any) => {
if (record.status == 0) {
return true
} else {
return false
}
},
},
},
opeColums: [
{
type: 'delete',
title: '删除',
key: 'delete',
},
{
type: 'edit',
title: '编辑',
key: 'edit',
},
{
type: 'punish',
title: '发布',
key: 'punish',
},
{
type: 'cancel',
title: '撤销发布',
key: 'cancel',
},
],
},
])
const dataSource = ref<DataItem[]>([
{
forewarning: 0,
id: '1',
status: 0,
pay_money: 34,
},
{
forewarning: 1,
id: '2',
status: 1,
pay_money: 56,
},
{
forewarning: 2,
is: '3',
status: 0,
pay_money: 34,
},
{
forewarning: 3,
id: '4',
status: 1,
pay_money: 34,
},
])
const configData = ref<configData>({
viewConfig: <tableViewConfig>{
rowKey: 'id',
bordered: true,
isHeight: true,
checkType: 'checkbox',
},
cusPagination: <pageConfig>{
current: 1,
pageSize: 20,
total: 4,
},
footerConfig: {
totalSum: {
titleKey: 'monetaryAll',
title: '总计',
data: {
pay_money: 158,
},
},
checkedSum: {
title: '选中合计',
titleKey: 'monetaryAll',
totalKey: ['pay_money'],
},
customFooter: {
titleKey: 'monetaryAll',
title: '收款',
data: {
pay_money: 4400,
},
},
},
})
let selectData: any = ref([])
//页码切换
const pageChange = (page: number, pageSize: number) => {}
//右侧操作列操作按钮
const handleOperate = (code: string, record: DataItem, index: number) => {}
//多选
const handleSelection = (selectedRows: DataItem[]) => {}
//清除选中项
const clearCheckData = () => {
tableRef.value.clearSelected()
}
//表格行展开事件
const onExpand = (expanded: boolean, record: any) => {}
</script>
<style lang="less" scoped>
#app {
padding: 8px;
background-color: #fff;
}
</style>属性 Props
| 参数 | 说明 | 类型 | 参数说明 | 是否必传 |
|---|---|---|---|---|
| columns | 表格列 | columnItem[] | 参考columns 说明 | 是 |
| dataSource | 表格数据 | DataItem[] | [] | 是 |
| configData | 表格基础配置 | configData | 参考configData 说明 | 是 |
| eleDataObj | 可编辑单元格为 Select 或 TreeSelect 时的下拉数据 | Record<string, any> | { 字典code或字段名:下拉数据 } | 否 |
| unitConfig | 表格金额展示格式化需要保留的金额位数,默认按照单位为元时格式化,保留两位小数 | {defaultVal: Units} | 参考Units | 否 |
事件 Events
| 事件名 | 说明 | 回调参数 | 参数说明 |
|---|---|---|---|
| operate | 列表行内操作按钮事件 | (code: string, record: DataItem, index: number) | code 当前按钮编码 / record 当前行数据 / index 当前行序号 |
| pageChange | 页码或者当前页显示条数变更 | (page: number, pageSize: number) | page 当前页码 / pageSize 每页显示条数 |
| handleSelection | 列表单选或多选选中数据变更 | (selectedRows: array) | 单选或多选的选中项 |
| handleItemClick | 单元格单击事件 | (record: DataItem, rowIndex: number, column: columnItem) | record 当前行数据 / rowIndex 当前行序号 / column 当前列 |
| onExpand | 行展开时触发 | (expanded: boolean, record: any) | expanded 是否展开 / record 展开的行的数据 |
| tableFormChange | 表格可编辑时单元格内容change事件 | ({value, column, index, record}) | value 当前值 / record 当前行数据 / index 当前行序号 / column 当前列 |
方法 Methods
| 方法名称 | 说明 |
|---|---|
| clearSelected | 清空表格选中项 |
插槽 Slots
| 插槽名称 | 说明 | 参数 |
|---|---|---|
| customEllipsis | {column 当前列配置信息,record 当前行数据} | |
| expandedRowRender | {record 当前行数据, index 当前行序号, indent 缩进距离, expanded 当前行展开状态} |
参数说明
columns 说明
| 属性名 | 说明 | 类型 | 可选值 |
|---|---|---|---|
| title | 对应列显示的标题 | String | |
| dataIndex | 对应列字段名 | String | |
| align | 列对齐方式 | String | 'center' / 'left' / 'right' |
| control_type | 可编辑单元格组件 | Control_Type | 参考Control_Type |
| configs | 可编辑单元格内组件配置信息 | columnConfigs | 参考columnConfigs 说明 |
| opeColums | 操作列按钮 | opeColumnItem[] | 参考opeColumnItem 说明 |
| data_type | 数据类型(针对金额格式化,其余类型暂不做处理) | DataType | 参考DataType,只对 money 和 minusMoney 类型做了格式化处理 |
| customRender | 生成复杂数据的渲染函数 | Function({text, record, index, column}) {} | |
| visible | 当前列是否显示 | Boolean | true / false |
| moreText | 操作列更多按钮现显示文字 | String | 默认“更多” |
| maxLength | 操作列按钮超过几个显示更多 | Number | 默认 3 个 |
| ele_code | 可编辑单元格为 Select 或 TreeSelect 时的下拉字典 code | String | '' |
| resizable | 是否支持可拖拽调整宽度 | Boolean | true / false,默认 true |
| customEllipsis | 是否需要自定义插槽显示气泡卡片 | Boolean | true / false,默认 false |
| opeShowType | 操作列按钮根据传入的禁用方法处理按钮在当前行的显隐或是否禁用状态类型 | OpeControlType | 参考OpeControlType,默认 hide |
| operateConfigs | 操作列按钮相关配置信息 | [x: string]: {disabledCondition?: Function} | disabledCondition 单个按钮在满足该条件时禁用或隐藏 |
| isClick | 操作列是否可点击 | Boolean | true / false |
| jump_group_id | 操作列点击可配置跳转视图的视图id | String | '' |
备注:其余属性可参考Ant Design Vue Table
configData 说明
| 属性名 | 说明 | 类型 | 参数说明 | 是否必传 |
|---|---|---|---|---|
| viewConfig | 基础配置 | tableViewConfig | 参考viewConfig 说明 | 是 |
| footerConfig | 合计行配置 | summarys | { totalSum: 参考totalSum 总计说明 , checkedSum: 参考checkedSum 勾选合计说明 , customFooter: 参考customFooter 自定义底部数据说明} | 否 |
| cusPagination | 页码配置 | pageConfig | {pageSize: 每页显示条数, current: 当前页码, total: 数据条数} | 否 |
columnConfigs 说明
| 属性名 | 说明 | 类型 | 参数说明 | 是否必传 |
|---|---|---|---|---|
| disabled | 组件是否禁用 | Boolean | true / false | 否 |
| maxlength | 最大长度 | number | 否 | |
| showCount | 是否展示字数 | boolean | true / false | |
| max | inputNumber 组件可输入的最大值 | number | 否 | |
| min | inputNumber 组件可输入的最小值 | number | 否 | |
| precision | 数值精度 | number | 否 | |
| allowClear | 可以点击清除图标删除内容 | boolean | true / false | 否 |
| fieldNames | 自定义节点 label、value、options 的字段 | object | { label: label, value: value, options: options } | 否 |
| showBtn | input 组件是否显示右侧选择按钮 | boolean | true / false | 否 |
| chooseModal | input 组件右侧选择按钮单击事件 | Function | (record: object, index: number, column: object) | record 当前行数据 / index 行序号 / column 当前列配置信息 |
| picker | 日期选择器类型 | PickerMode | date / week / month / quarter / year | 否 |
| format | 日期组件显示格式化 | formatType | 参考dayjs | 否 |
| showTime | 日期组件是否显示时分秒 | boolean | true / false | 否 |
| mode | 设置 Select 的模式为多选或标签 | 'multiple' / 'tags' / 'SECRET_COMBOBOX_MODE_DO_NOT_USE' / undefined | 否 | |
| placeholder | 输入框提示文字 | string | ||
| controls | inputNumber 组件是否显示增减按钮 | boolean | true / false | 否 |
| optionsData | select 或者 treeSelect 的下拉框数据 | Array | ||
| formatter | 自定义渲染函数(可以为 html) | (record)=>{} | - | - |
| align | 组件类型为 InputNumber 时数值对齐方式 | string | 'right' / 'left' / 'center',默认'left' | 否 |
| isAllCheck | 组件类型为 CheckBox 时是否需要全选 | boolean | true / false,默认 false | 否 |
| buttonStyle | 组件类型为 Radio 时的显示类型 | string | 'Radio' / 'RadioButton',默认'Radio' | 否 |
| showType | 组件类型为 Radio 且显示类型为 RadioButton 时的组件样式,描边或填色 | string | 'outline' / 'solid',默认'outline' | 否 |
| className | 给组件添加 class 属性 | string | 否 | |
opeColumnItem 说明
| 属性名 | 说明 | 类型 | 参数说明 | 是否必传 |
|---|---|---|---|---|
| title | 按钮名称 | String | '' | 是 |
| key | 按钮标识 | String | '' | 是 |
| type | 按钮类型 | String | '' | 是 |
viewConfig 说明
| 属性名 | 说明 | 类型 | 参数说明 | 是否必传 |
|---|---|---|---|---|
| bordered | 是否有边框 | Boolean | true / false | 否 |
| checkType | 是否需要选择,单选或者多选 | String | '' / 'checkbox' / 'radio',注意:checkType和rowSelection只能选其一 | 否 |
| showIndex | 是否显示序号列 | Boolean | true / false | 否 |
| rowKey | 表格行 key 的取值,可以是字符串或一个函数 | Function(record):string | 'key' | 是 |
| isShowHeader | 是否显示页头 | Boolean | true / false(可通过 slot 插槽设置页头) | 否 |
| isHeight | 内容区域的高度是否动态计算 | Boolean | true / false,默认 true | 否 |
| scroll | 是否可滚动,也可以指定滚动区域的宽、高 | Object | {y: scrollHeight, x: '100%'} | 否 |
| selectedKeys | 可选择表格的默认选中项 | Array | rowKey 组成的数组 | 否 |
| isDrag | 表格行是否支持拖拽 | Boolean | true / false(默认false) | 否 |
备注:其余属性可参考Surely Vue Table
totalSum 总计说明
| 属性名 | 类型 | 说明 | 可选值 |
|---|---|---|---|
| title | String | 总计 title | |
| titleKey | String | 总计 title 在哪列显示 | 当前表格的所有 dataIndex |
| data | Object | 总计数据(由于需要跨页计算全部数据总计,数据需后台返回) |
checkedSum 勾选合计说明
| 属性名 | 类型 | 说明 | 可选值 |
|---|---|---|---|
| title | String | 合计 title | |
| titleKey | String | 合计 title 在哪列显示 | 当前表格的所有 dataIndex |
| totalKey | String | 需要计算合计的列(当前仅支持单项) | 当前表格的所有 dataIndex |
customFooter 自定义底部数据说明
| 属性名 | 类型 | 说明 | 可选值 | 是否必传 |
|---|---|---|---|---|
| title | String | 自定义底部 title | 是 | |
| titleKey | String | 自定义底部 title 在哪列显示 | 当前表格的所有 dataIndex | 是 |
| data | DataItem | 要展示的数据 | 是 |
Demo
表格列显示自定义组件
- column 的 control_type 配置成 'Render'
- 在 configs 里写 cusRender 函数(必须使用 vue 的 h 函数写)
import { Progress } from 'ant-design-vue'
const tableColumns: columnItem[] = [
{
title: '金额',
dataIndex: 'pay_money',
align: 'right',
control_type: 'Render',
configs: {
cusRender: (record) => {
return h(Progress, { percent: Number(record.pay_money || 0) })
},
},
},
]import { Progress } from 'ant-design-vue'
const tableColumns: columnItem[] = [
{
title: '金额',
dataIndex: 'pay_money',
align: 'right',
control_type: 'Render',
configs: {
cusRender: (record) => {
return h(Progress, { percent: Number(record.pay_money || 0) })
},
},
},
]表格列显示自定义气泡提示
- column 对应列 加上 customEllipsis 属性
const tableColumns: columnItem[] = [
{
title: '金额',
dataIndex: 'pay_money',
align: 'right',
customEllipsis: true,
},
]const tableColumns: columnItem[] = [
{
title: '金额',
dataIndex: 'pay_money',
align: 'right',
customEllipsis: true,
},
]- 组件那自定义气泡内容插槽,插槽名称 customEllipsis,内容写的时候需要判断一下 column 是否是需要显示气泡的列如果不写插槽,默认是显示当前文本
<GapTable
ref="tableRef"
:columns="tableColumns"
:dataSource="dataSource"
@page-change="pageChange"
@operate="handleOperate"
:config-data="configData"
@handleSelection="handleSelection"
>
<template #customEllipsis="scope">
<div>
<div v-if="scope?.column?.dataIndex === 'bill_status_display'">
bill_status_display_test
</div>
</div>
</template>
</GapTable><GapTable
ref="tableRef"
:columns="tableColumns"
:dataSource="dataSource"
@page-change="pageChange"
@operate="handleOperate"
:config-data="configData"
@handleSelection="handleSelection"
>
<template #customEllipsis="scope">
<div>
<div v-if="scope?.column?.dataIndex === 'bill_status_display'">
bill_status_display_test
</div>
</div>
</template>
</GapTable>