Skip to content

ProTable 超级表格

将搜索表单、表格主体、分页组件封装在一起的超级表格,最少只需要传递一个函数和一个列配置即可生成带搜索表单、表格主体、分页的组件

CHANGELOG

安装

警告

el-protable是基于element-plus封装的,所以需要先安装element-plus 默认你已安装了element-plus,并引入了ElementPlus的css文件,如果没有请先安装并引入

sh
yarn add @suite-kit/el-protable
# or
npm i @suite-kit/el-protable
yarn add @suite-kit/el-protable
# or
npm i @suite-kit/el-protable

引入样式文件

ts
// main.ts
import "@suite-kit/el-protable/dist/style.css";
// main.ts
import "@suite-kit/el-protable/dist/style.css";

基础用法

如果没有什么特殊要求,给组件传递一个请求函数request-apicolumns就能生成一个基础表格

<template>
  <div class="table">
    <ProTable :columns="columns" :request-api="getDataApi"></ProTable>
  </div>
</template>

<script setup lang="ts">
import ProTable, { ColumnProps } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";
import { dayjs } from "element-plus";

const columns: ColumnProps[] = [
  { label: "姓名", prop: "name", search: { el: "text" } },
  { label: "年龄", prop: "age" },
  {
    label: "性别",
    prop: "gender",
    enum: [
      { label: "男", value: 1 },
      { label: "女", value: 0 },
    ],
    search: { el: "select" },
  },
  {
    label: "创建时间",
    prop: "createTime",
    render({ row }) {
      return dayjs(row.createTime).format("YYYY-MM-DD HH:mm:ss");
    },
    search: { el: "date-picker" },
  },
];
</script>

使用本地数据

如果不想使用request-api,你可以直接传递data属性,数据会直接传递到el-table

TIP

使用本地数据时,表格搜索功能不再生效

<template>
	<div class="table">
		<ProTable :columns="columns" :data="data"></ProTable>
	</div>
</template>

<script setup lang="ts">
import ProTable, { ColumnProps } from "@suite-kit/el-protable";
import { dayjs } from "element-plus";

const data = Array(20)
	.fill(undefined)
	.map((_, index) => {
		return {
			name: `张三` + index,
			age: index + 1,
			gender: index % 2,
			createTime: dayjs(),
		};
	});

const columns: ColumnProps[] = [
	{ label: "姓名", prop: "name" },
	{ label: "年龄", prop: "age" },
	{
		label: "性别",
		prop: "gender",
		enum: [
			{ label: "男", value: 1 },
			{ label: "女", value: 0 },
		],
	},
	{
		label: "创建时间",
		prop: "createTime",
		render({ row }) {
			return dayjs(row.createTime).format("YYYY-MM-DD HH:mm:ss");
		},
	},
];
</script>

自定义表格渲染

如果需要自定义表格渲染,可以在 column 上传递headerRenderrender属性,或者使用插槽

对于表格操作列,推荐的prop名称是 operation

<template>
	<div class="table">
		<ProTable :columns="columns" :request-api="getDataApi">
			<template #title>表格标题,也可使用title属性</template>
			<template #action>
				<el-button type="primary">表格操作区</el-button>
			</template>
			<template #tools>
				<el-button type="primary">表格工具栏</el-button>
			</template>
			<template #nameHeader> 表头插槽 prop+'Header'</template>
			<template #name="{ $index }"> 表格内容插槽{{ $index }}</template>
			<template #append> 表尾合计行</template>
			<template #operation>
				<el-button link type="danger">删除</el-button>
			</template>
		</ProTable>
	</div>
</template>

<script setup lang="ts">
import ProTable, { ColumnProps } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";
import { dayjs, ElButton } from "element-plus";

const columns: ColumnProps[] = [
	{ label: "姓名", prop: "name", search: { el: "text" } },
	{
		label: "年龄",
		prop: "age",
		headerRender(scope) {
			return "表头渲染函数";
		},
		render(scope) {
			return "表格渲染函数";
		},
	},
	{
		label: "性别",
		prop: "gender",
		enum: [
			{ label: "男", value: 1 },
			{ label: "女", value: 0 },
		],
		search: { el: "select" },
	},
	{
		label: "创建时间",
		prop: "createTime",
		render({ row }) {
			return dayjs(row.createTime).format("YYYY-MM-DD HH:mm:ss");
		},
		search: { el: "date-picker" },
	},
	{
		label: "操作",
		prop: "operation",
	},
];
</script>

自定义搜索项

如果需要自定义搜索项,可以在column.search上传递render属性。非不得已的情况下,不推荐自定义搜索项,因为无论是使用h 函数还是使用jsx对新手都极不友好

<template>
	<div class="table">
		<ProTable :columns="columns" :request-api="getDataApi"></ProTable>
	</div>
</template>

<script setup lang="tsx">
import ProTable, { ColumnProps, SearchRenderScope } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";
import { dayjs, ElAutocomplete } from "element-plus";
import { onMounted, ref } from "vue";
interface RestaurantItem {
	value: string;
	link: string;
}
const restaurants = ref<RestaurantItem[]>([]);
const querySearch = (queryString: string, cb: any) => {
	const results = queryString ? restaurants.value.filter(createFilter(queryString)) : restaurants.value;
	cb(results);
};
const createFilter = (queryString: string) => {
	return (restaurant: RestaurantItem) => {
		return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
	};
};
const loadAll = () => {
	return [
		{ value: "vue", link: "https://github.com/vuejs/vue" },
		{ value: "element", link: "https://github.com/ElemeFE/element" },
		{ value: "cooking", link: "https://github.com/ElemeFE/cooking" },
		{ value: "mint-ui", link: "https://github.com/ElemeFE/mint-ui" },
		{ value: "vuex", link: "https://github.com/vuejs/vuex" },
		{ value: "vue-router", link: "https://github.com/vuejs/vue-router" },
		{ value: "babel", link: "https://github.com/babel/babel" },
	];
};

onMounted(() => {
	restaurants.value = loadAll();
});

const columns: ColumnProps[] = [
	{
		label: "姓名",
		prop: "name",
		search: {
			// 使用渲染函数
			render(scope: SearchRenderScope) {
				return (
					<ElAutocomplete
						modelValue={scope.searchParam["name"]}
						fetchSuggestions={querySearch}
						placeholder="请输入姓名"
						onUpdateModelValue={(value: string) => {
							scope.searchParam["name"] = value;
						}}></ElAutocomplete>
				);
			},
		},
	},
	{ label: "年龄", prop: "age" },
	{
		label: "性别",
		prop: "gender",
		enum: [
			{ label: "男", value: 1 },
			{ label: "女", value: 0 },
		],
		search: {
			// 使用默认预设
			el: "select",
		},
	},
	{
		label: "创建时间",
		prop: "createTime",
		render({ row }) {
			return dayjs(row.createTime).format("YYYY-MM-DD HH:mm:ss");
		},
	},
];
</script>

响应式搜索表单

搜索表单使用@suite-kit/Grid构建,支持响应式。

默认响应式配置是{ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 },一个搜索项占一列,可以根据需要自行配置,同时可设置order 来改变搜索项展示的顺序,默认是按照 columns 的顺序展示

<template>
  <div class="table">
    <ProTable :columns="columns" :request-api="getDataApi"></ProTable>
  </div>
</template>

<script setup lang="ts">
import ProTable, { ColumnProps } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";
import { dayjs } from "element-plus";

const columns: ColumnProps[] = [
  { label: "姓名", prop: "name", search: { el: "text" } },
  { label: "年龄", prop: "age" },
  {
    label: "性别",
    prop: "gender",
    enum: [
      { label: "男", value: 1 },
      { label: "女", value: 0 },
    ],
    search: { el: "select" },
  },
  {
    label: "创建时间",
    prop: "createTime",
    render({ row }) {
      return dayjs(row.createTime).format("YYYY-MM-DD HH:mm:ss");
    },
    search: {
      el: "date-picker",
      props: { type: "datetimerange" },
      // 设置响应式列
      span: 2,
      // 设置表单项排序
      order: 1,
    },
  },
];
</script>

使用函数式 enum

对于一些需要使用字段或者枚举值来格式化的数据来说,enum 除了可以传确切的值意外,还可以使用一个函数

TIP

如果要使用函数,请注意函数的返回值必须是一个对象,且 enum 数据要在对象的 data 属性中

<template>
  <div class="table">
    <ProTable :columns="columns" :request-api="getDataApi"></ProTable>
  </div>
</template>

<script setup lang="ts">
import ProTable, { ColumnProps } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";

//模拟函数请求
const getGenderEnum = async () => {
  // 必须返回一个 {data:any}
  return {
    data: [
      { label: "男", value: 1 },
      { label: "女", value: 0 },
    ],
  };
};

const columns: ColumnProps[] = [
  { label: "姓名", prop: "name", search: { el: "text" } },
  { label: "年龄", prop: "age" },
  {
    label: "性别",
    prop: "gender",
    enum: getGenderEnum,
    search: { el: "select" },
  },
];
</script>

下拉框远程搜索

远程搜索请参考el-select 远程搜索

<template>
  <div class="table">
    <ProTable :columns="columns" :request-api="getDataApi"></ProTable>
  </div>
</template>

<script setup lang="ts">
import ProTable, { ColumnProps } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";
import { ref } from "vue";
const nameList = ref([
  { label: "张三", value: "张三" },
  { label: "李四", value: "李四" },
  { label: "王五", value: "王五" },
  { label: "赵六", value: "赵六" },
  { label: "田七", value: "田七" },
  { label: "王麻子", value: "王麻子" },
  { label: "李二狗", value: "李二狗" },
  { label: "张三丰", value: "张三丰" },
  { label: "王二麻子", value: "王二麻子" },
]);
const options = ref<any>([]);
const remoteMethod = (query: string) => {
  options.value.length = 0;
  if (query) {
    setTimeout(() => {
      options.value = nameList.value.filter((item) =>
        item.label.toLowerCase().includes(query.toLowerCase())
      );
    }, 200);
  }
};
const columns: ColumnProps[] = [
  {
    label: "姓名",
    prop: "name",
    enum: options,
    search: {
      el: "select",
      props: {
        remote: true,
        filterable: true,
        remoteMethod,
      },
    },
    isFilterEnum: false,
  },
  { label: "年龄", prop: "age" },
];
</script>

搜索项联动

某些情况下,你可能需要类似于省市区联动搜索,推荐使用el-cascader,也可以按照下方的示例自己实现搜索框联动

<template>
	<div class="table">
		<ProTable :columns="columns" :request-api="getDataApi" ref="table"></ProTable>
	</div>
</template>

<script setup lang="ts">
import ProTable, { ProTableInstance, ColumnProps } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";
import { ref } from "vue";

// 有两组部门数据,一组属于性别男,一组数据性别女
const departA = [
	{ label: "部门1", value: 0 },
	{ label: "部门2", value: 1 },
	{ label: "部门3", value: 2 },
	{ label: "部门4", value: 3 },
	{ label: "部门5", value: 4 },
];
const departB = [
	{ label: "部门A", value: 5 },
	{ label: "部门B", value: 6 },
	{ label: "部门C", value: 7 },
	{ label: "部门D", value: 8 },
	{ label: "部门E", value: 9 },
];
const table = ref<ProTableInstance>();
const departEnum = ref<typeof departA>([]);
const genderChange = (val: number) => {
	table.value!.searchParam["departId"] = null;
	if (val) {
		departEnum.value = departA;
	} else {
		departEnum.value = departB;
	}
};
const columns: ColumnProps[] = [
	{ label: "姓名", prop: "name" },
	{ label: "年龄", prop: "age" },
	{
		label: "性别",
		prop: "gender",
		enum: [
			{ label: "男", value: 1 },
			{ label: "女", value: 0 },
		],
		search: { el: "select", props: { onChange: genderChange } },
	},
	{
		label: "部门",
		prop: "departId",
		enum: departEnum,
		search: { el: "select-v2" },
		isShow: false,
	},
];
</script>

搜索项默认值为后端数据

某些特殊情况下,你的某个下拉搜索项的默认值可能是从后端获取的

request-auto设置false,在onMounted中拿到ProTable实例的enumMap后手动给searchInitParamsearchParam赋值再手动调用getTableList

<template>
	<div class="table">
		<ProTable :columns="columns" :request-api="getDataApi" :request-auto="false" ref="table"></ProTable>
	</div>
</template>

<script setup lang="ts">
import ProTable,{ ColumnProps, ProTableInstance } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";
import { ref, watch } from "vue";
const table = ref<ProTableInstance>();
// 模拟下拉数据为后台接口
const getGenderEnum = async () => {
	return {
		data: [
			{ label: "男", value: 1 },
			{ label: "女", value: 0 },
		],
	};
};
const columns: ColumnProps[] = [
	{ label: "姓名", prop: "name", search: { el: "text" } },
	{ label: "年龄", prop: "age" },
	{
		label: "性别",
		prop: "gender",
		enum: getGenderEnum,
		search: { el: "select" },
	},
];
// 将默认性别设置成第一条数据
watch(
	() => table.value?.enumMap.get("gender"),
	gender => {
		if (gender) {
			table.value!.searchInitParam["gender"] = gender[0].value;
			table.value!.searchParam["gender"] = gender[0].value;
			table.value?.getTableList();
		}
	},
);
</script>

行拖动

只需要给column加一列{type:"drag"}就可以生成一条用来拖动的列

拖动排序,改变的只是dom结构,并不会改变表格数据,可以监听drag-sort事件

INFO

在文档中drag不会生效

<template>
	<div class="table">
		<ProTable :columns="columns" :request-api="getDataApi" @drag-sort="onDrag"></ProTable>
	</div>
</template>

<script setup lang="ts">
import ProTable, { ColumnProps } from "@suite-kit/el-protable";
import { getDataApi } from "../../../fetch";
import { dayjs } from "element-plus";

const onDrag = (newIndex?: number, oldIndex?: number, data?: any) => {
	console.log(newIndex, oldIndex, data);
};

const columns: ColumnProps[] = [
	{ type: "drag" },
	{ label: "姓名", prop: "name", search: { el: "text" } },
	{ label: "年龄", prop: "age" },
	{
		label: "性别",
		prop: "gender",
		enum: [
			{ label: "男", value: 1 },
			{ label: "女", value: 0 },
		],
		search: { el: "select" },
	},
	{
		label: "创建时间",
		prop: "createTime",
		render({ row }) {
			return dayjs(row.createTime).format("YYYY-MM-DD HH:mm:ss");
		},
		search: { el: "date-picker" },
	},
];
</script>

属性

TIP

@suite-kit/ElProTable扩展了ElTable,对于ElTable的属性在@suite-kit/ElProTable内部使用$attrs 传递给ElTable组件,所以在@suite-kit/ElProTable 组件上没有类型提示。参考ElTable

属性名说明类型默认值
columns表格列配置ColumnsProps[]——
data表格数据,优先级要高于request-apiany[]
requestApi数据源(params:any)=>Promise<any>
requestAuto是否在组件加载后自动执行请求(request-apibooleantrue
requestErrorrequest-api请求错误回调(params: any) => void
dataCallback返回数据的回调函数,可以对数据进行处理(data: any)=> ({ data: any[] } | { list: any[]; total: number; pageSize?: number; pageNum?: number });
title表格标题string
pagination分页器的配置,可根据el-pagination传入相同的配置PaginationConfig | boolean;true
initParam初始化请求参数,会传递给request-api。如果想在initPrams数据变化时自动刷新表格数据,initPrams需要是reactive创建的代理any
borderElTableborderbooleantrue
toolButton表格顶部右侧工具栏,可以传递布尔值来控制显示隐藏,也可以额传入一个 string[]来控制具体的某一个['refresh','setting','search'] | booleantrue
rowKeyElTablerow-keystringid
searchCol表格搜索项每列占比配置number | Record<BreakPoint, number>{ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 }

插槽

插槽说明
defaultElTable默认插槽
append插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。
empty当数据为空时自定义的内容
title表格标题
action表格操作区插槽
tools表格工具栏插槽
column.prop表格列具名插槽。示例:如果有个列的 prop 属性是type,那suite-kit/ElProTable中也会有一个 <slot name="type"></slot>的插槽
column.propHeader表格列表头部分具名插槽。示例:如果有个列的 prop 属性是type,那suite-kit/ElProTable中也会有一个 <slot name="typeHeader"></slot>的插槽。推荐使用headerRender
pagination分页器

事件

TIP

suite-kit/ElProTable继承了ElTable中除selection-change 外的所有事件。参考Table 事件

以下是suite-kit/ElProTable独有事件

事件名说明参数
search搜索时触发
refresh刷新时触发
request请求数据时触发,在使用data不会触发
reset重置搜索表单数据后触发
drag-sort拖拽排序后触发(newIndex,oldIndex,data)

实例

以下是通过 ref 获取到suite-kit/ElProTable的实例的属性

你可以从@suite-kit/el-protable中导入ProTableInstance类型

名称描述类型
element内部el-table的实例Ref<InstanceType<typeof ElTable>>
enumMap收集的字典Ref<Map<string,{[key:string]:any}[]>>
tableData表格数据any[]
pageable分页配置{pageNum: number;pageSize: number;total: number;}
searchParam搜索表单绑定值{[key:string]:any}
searchInitParam初始化搜索参数{[key:string]:any}
getTableList手动调用传入的request-api,未执行search之前只会携带searchInitParam,不会携带搜索表单数据()=>void
search主要用于将搜索表单的数据合并到总搜索参数中再执行getTableList()=>void
rest重置搜索表单,将所有参数还原(如果有),再执行getTableList()=>void
handleSizeChange手动设置分页器每页条数(val:number)=>void
handleCurrentChange手动设置分页器当前页(val:number)=>void
clearSelection清空表格所选数据,其实就是 el-table 的 clearSelection()=>void
isSelected当前是否有选择的数据Ref<boolean>
selectedList选择的数据Ref<any[]>
selectedListIds选择的数据的row-key,row-key 默认是idRef<string[]>

ColumnsProps

TIP

ColumnProps包含了ElTableColumn中除children,renderCell,renderHeader,type 外所有的属性,参考Table-column 属性

所有属性均为非必传

属性名描述类型
type列类型:序号列、选择列、展开列、拖拽列。"index" | "selection" | "expand" | "drag"
tag数据是否通过el-tag渲染,需要配合enum使用boolean
tip表头的tooltip信息,如果没有单独设置search.tip,那么此信息也会显示在搜索表单项的tooltip上。对应的表头插槽或渲染函数会覆盖tooltip,请自行渲染string | () => VNodeChild
isShow是否在表格显示当前列boolean | Ref<boolean>
search搜索配置SearchProps
enum枚举字典EnumProps[] | ((params?: any) => Promise<{data:any}>) | Ref<EnumProps[]>
isFilterEnum当前单元格值是否根据 enum 格式化,默认为trueboolean
fieldNames指定从enum中获取labelvaluechildren的属性值{label:string,value:string,children?:string}
headerRender自定义表头渲染,优先级高于插槽({column,$index})=>VNode
render自定义单元格渲染,也可以在组件上使用同prop名称具名插槽,优先级高于插槽({column,$index})=>VNode
_children多级表头ColumnProps[]

SearchProps

搜索项配置

属性名描述类型
el要渲染的表单组件SearchType
props传递给表单组件的属性,参考 Element 官网any
key指定绑定值的名称,默认是 Columns 的propsrting
order搜索项排序从大到小number
span搜索项所占用的列数(grid 布局),默认 1number | { xs: number, sm: number, md: number, lg: number, xl: number }
offset搜索项左侧偏移列数number | { xs: number, sm: number, md: number, lg: number, xl: number }
defaultValue搜索项默认值any
tip表单项的提示信息,如果未设置会使用column上的tip(如果有)string|()=>VNodeChild
render自定义搜索内容渲染(tsx/h)(scope: SearchRenderScope) => VNode

Typescript

点我查看 TS 类型代码
ts
export type BreakPoint = "xs" | "sm" | "md" | "lg" | "xl";

export type SearchProps = {
 el?: SearchType; // 当前项搜索框的类型
 props?: any; // 搜索项参数,根据 element plus 官方文档来传递,该属性所有值会透传到组件
 key?: string; // 当搜索项 key 不为 prop 属性时,可通过 key 指定
 order?: number; // 搜索项排序(从大到小)
 span?: number | Record<BreakPoint, number>; // 搜索项所占用的列数,默认为1列
 offset?: number | Record<BreakPoint, number>; // 搜索字段左侧偏移列数
 defaultValue?: any; // 搜索项默认值
 tip?: (() => VNodeChild) | string; // 搜索项提示文字
 render?: (scope: SearchRenderScope) => VNodeChild; // 自定义搜索内容渲染(tsx语法)
};

export type SearchType =
 | "text" // 文本框
 | "number" // 数字输入框
 | "select" // 下拉选择框
 | "select-v2" // 下拉选择框v2
 | "tree-select" // 树形选择器
 | "cascader" // 级联选择器
 | "date-picker" // 日期选择器
 | "time-picker" // 时间选择器
 | "time-select" // 时间选择框
 | "switch" // 开关
 | "slider"; // 滑块

export type SearchRenderScope = {
 searchParam: { [key: string]: any };
 clearable: boolean;
 options: EnumProps[];
 data: EnumProps[];
};

export interface EnumProps {
 label?: string; // 选项框显示的文字
 value?: string | number | boolean | any[]; // 选项框值
 disabled?: boolean; // 是否禁用此选项
 tagType?: "success" | "info" | "warning" | "danger"; // 当ColumnsProps上的tag为true时,此选项会指定 el-tag 显示类型
 children?: EnumProps[]; // 为树形选择时,可以通过 children 属性指定子选项
 [key: string]: any; // 其他属性
}

export interface ColumnProps<T = any>
 extends Partial<Omit<TableColumnCtx<T>, "children" | "renderCell" | "renderHeader" | "type">> {
 type?: "index" | "selection" | "expand" | "drag";
 tag?: boolean; // 是否是标签展示
 isShow?: boolean | Ref<boolean>; // 是否显示在表格当中
 search?: SearchProps; // 搜索项配置
 enum?: EnumProps[] | ((params?: any) => Promise<any>) | Ref<EnumProps[]>; // 枚举类型(字典)
 isFilterEnum?: boolean; // 当前单元格值是否根据 enum 格式化(示例:enum 只作为搜索项数据)
 fieldNames?: FieldNamesProps; // 指定 label && value && children 的 key 值
 tip?: (() => VNodeChild) | string; // 表头提示文字
 headerRender?: (scope: HeaderRenderScope<T>) => VNode; // 自定义表头内容渲染(tsx/h)
 render?: (scope: RenderScope<T>) => VNode | string; // 自定义单元格内容渲染(tsx/h)
 _children?: ColumnProps<T>[]; // 多级表头 为了和ElTable的children属性做区分,否则会有问题
}
export type BreakPoint = "xs" | "sm" | "md" | "lg" | "xl";

export type SearchProps = {
 el?: SearchType; // 当前项搜索框的类型
 props?: any; // 搜索项参数,根据 element plus 官方文档来传递,该属性所有值会透传到组件
 key?: string; // 当搜索项 key 不为 prop 属性时,可通过 key 指定
 order?: number; // 搜索项排序(从大到小)
 span?: number | Record<BreakPoint, number>; // 搜索项所占用的列数,默认为1列
 offset?: number | Record<BreakPoint, number>; // 搜索字段左侧偏移列数
 defaultValue?: any; // 搜索项默认值
 tip?: (() => VNodeChild) | string; // 搜索项提示文字
 render?: (scope: SearchRenderScope) => VNodeChild; // 自定义搜索内容渲染(tsx语法)
};

export type SearchType =
 | "text" // 文本框
 | "number" // 数字输入框
 | "select" // 下拉选择框
 | "select-v2" // 下拉选择框v2
 | "tree-select" // 树形选择器
 | "cascader" // 级联选择器
 | "date-picker" // 日期选择器
 | "time-picker" // 时间选择器
 | "time-select" // 时间选择框
 | "switch" // 开关
 | "slider"; // 滑块

export type SearchRenderScope = {
 searchParam: { [key: string]: any };
 clearable: boolean;
 options: EnumProps[];
 data: EnumProps[];
};

export interface EnumProps {
 label?: string; // 选项框显示的文字
 value?: string | number | boolean | any[]; // 选项框值
 disabled?: boolean; // 是否禁用此选项
 tagType?: "success" | "info" | "warning" | "danger"; // 当ColumnsProps上的tag为true时,此选项会指定 el-tag 显示类型
 children?: EnumProps[]; // 为树形选择时,可以通过 children 属性指定子选项
 [key: string]: any; // 其他属性
}

export interface ColumnProps<T = any>
 extends Partial<Omit<TableColumnCtx<T>, "children" | "renderCell" | "renderHeader" | "type">> {
 type?: "index" | "selection" | "expand" | "drag";
 tag?: boolean; // 是否是标签展示
 isShow?: boolean | Ref<boolean>; // 是否显示在表格当中
 search?: SearchProps; // 搜索项配置
 enum?: EnumProps[] | ((params?: any) => Promise<any>) | Ref<EnumProps[]>; // 枚举类型(字典)
 isFilterEnum?: boolean; // 当前单元格值是否根据 enum 格式化(示例:enum 只作为搜索项数据)
 fieldNames?: FieldNamesProps; // 指定 label && value && children 的 key 值
 tip?: (() => VNodeChild) | string; // 表头提示文字
 headerRender?: (scope: HeaderRenderScope<T>) => VNode; // 自定义表头内容渲染(tsx/h)
 render?: (scope: RenderScope<T>) => VNode | string; // 自定义单元格内容渲染(tsx/h)
 _children?: ColumnProps<T>[]; // 多级表头 为了和ElTable的children属性做区分,否则会有问题
}

MIT License.