GeekerAdmin是什么
GeekerAdmin 是一款基于Vite3、vue3、Element Plus、pinia打造的包含动态路由、状态管理、权限控制等功能为一体的后台管理系统模板。
更新了什么
在此次ProTable组件更新中,我们:
- 重新设计了
ColumnProps的类型定义 - 重新设计了
SeachFromItem组件 - 现支持
el-table所有属性和事件,包括多级表头 - 搜索表单现拥有默认响应式布局,也支持手动设置
- 全部支持自定义的表头和单元格
更新解读(抢先版)
ColumnProps类型定义
原来的ColumnProps定义属性比较分散,类型也相对松散。
export interface ColumnProps {
type: TypeProp; // index | selection | expand(特殊类型)
prop: string; // 单元格数据(非特殊类型必填)
label: string; // 单元格标题(非特殊类型必填)
width: number | string; // 列宽
minWidth: number | string; // 最小列宽
isShow: boolean; // 是否显示在表格当中
sortable: boolean; // 是否可排序(静态排序)
fixed: FixedProp; // 固定列
align: AlignProp; // 表格列对齐方式(默认为 center)
tag: boolean; // 是否是标签展示
search: boolean; // 是否为搜索项
searchType: SearchType; // 搜索项类型
searchProps: { [key: string]: any }; // 搜索项参数,根据 element 文档来,标签自带属性 > props 属性
searchInitParam: string | number | boolean | any[]; // 搜索项初始值
enum: EnumProps[] | (() => Promise<any>); // 枚举类型(渲染值的字典)
renderHeader: (params: any) => any; // 自定义表头
}
在新版本中,我们通过各种引入了Element表单组件(常见的input、select、datepicker、timepicker等)的属性和El-Table-Column的属性。这意味着ColumnProps现在包含了el-table-column的大部分属性。对于原来的search*现在全部移到了search里面,并且传递不同的渲染项会有不同的类型提示。
Search 类型
export type BreakPoint = "xs" | "sm" | "md" | "lg" | "xl";
export type Responsive = {
span?: number;
offset?: number;
};
type BaseSearch = {
/*搜索字段的默认值*/
defaultValue?: any;
/*搜索表单用的数据名称,undefined时会使用column的prop属性*/
key?: string;
/*搜索字段的排序*/
order?: number;
/*搜索字段所占用的列数 默认为1*/
span?: number;
/*搜索字段左侧间隔列数*/
offset?: number;
} & Partial<Record<BreakPoint, Responsive>>;
interface Input {
/*input输入框*/
el: "input";
/*input输入框的props*/
props?: Partial<InputProps>;
}
interface Select {
el: "select";
props?: Partial<typeof ElSelect.__defaults>;
}
interface DatePicker {
el: "date-picker";
props?: Partial<any>; // 这个属性太多了,放在这里占地方,可以看源代码
}
interface TimePicker {
el: "time-picker";
props?: Partial<TimePickerDefaultProps>;
}
interface TimeSelect {
el: "time-select";
props?: Partial<TimeSelectProps>;
}
interface Switch {
el: "switch";
props?: Partial<SwitchProps>;
}
interface Slider {
el: "slider";
props?: Partial<SliderProps>;
}
interface TreeSelect {
el: "tree-select";
props?: Partial<TreeProps | typeof SelectProps>;
}
// 支持 input,select,detapicker,timepicker,timeselect,switch,slider,treeselect
type Search = BaseSearch & (Input | Select | DatePicker | TimePicker | TimeSelect | Switch | Slider | TreeSelect);
ColumnProps 类型
export interface ColumnProps<T = any>
extends Partial<Omit<TableColumnCtx<T>, "order" | "children" | "renderHeader" | "renderCell">> {
// index | selection | expand(特殊类型)
type?: TypeProp;
// 是否显示在表格当中
isShow?: boolean;
// 是否是标签展示
tag?: boolean;
/* 多级表头 */
_children?: ColumnProps<T>[];
/* 搜索菜单配置 */
search?: Search;
// 枚举类型(渲染值的字典)
enum?: EnumProps[] | (() => Promise<any>);
/*自定义字段名,针对于后端返回的enum不是 {label:string,value:string}的情况*/
fieldNames?: { label?: string; value?: string };
// 自定义表头
headerRender?: (data: T) => any;
/*自定义单元格*/
render?: (record?: T) => any;
}
SearchFormItem 组件
原来的SearchFormItem组件中,渲染input、select等是使用v-if来渲染,支持的表单项不多,并且不够灵活:
<!-- 旧的 -->
<template>
<!-- 文本框 -->
<template v-if="item.searchType == undefined || item.searchType == 'text'">
<el-input
v-model="searchParam[item.prop!]"
v-bind="item.searchProps"
placeholder="请输入"
:clearable="clearable(item)"
></el-input>
</template>
<!-- 下拉选择框 -->
<template v-if="item.searchType == 'select' || item.searchType == 'multipleSelect'">
<el-select
v-model="searchParam[item.prop!]"
v-bind="item.searchProps"
:multiple="item.searchType == 'multipleSelect'"
placeholder="请选择"
:clearable="clearable(item)"
>
<el-option
v-for="itemValue in item.enum"
:key="itemValue[item.searchProps?.value] ?? itemValue.value"
:label="itemValue[item.searchProps?.label] ?? itemValue.label"
:value="itemValue[item.searchProps?.value] ?? itemValue.value"
:disabled="itemValue.disabled"
/>
</el-select>
</template>
<!-- 下拉树形选择框 -->
<template v-if="item.searchType == 'treeSelect' || item.searchType == 'multipleTreeSelect'">
<el-tree-select
v-model="searchParam[item.prop!]"
v-bind="item.searchProps"
:multiple="item.searchType == 'multipleTreeSelect'"
:data="item.enum"
/>
</template>
<!-- 日期选择 -->
<template v-if="item.searchType == 'date'">
<el-date-picker
v-model="searchParam[item.prop!]"
v-bind="item.searchProps"
value-format="YYYY-MM-DD"
type="date"
placeholder="请选择日期"
:clearable="clearable(item)"
/>
</template>
<!-- 时间范围选择 -->
<template v-if="item.searchType == 'timerange'">
<el-time-picker
v-model="searchParam[item.prop!]"
v-bind="item.searchProps"
is-range
value-format="HH:mm:ss"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
:clearable="clearable(item)"
/>
</template>
<!-- 日期范围选择 -->
<template v-if="item.searchType == 'daterange'">
<el-date-picker
v-model="searchParam[item.prop!]"
v-bind="item.searchProps"
type="daterange"
value-format="YYYY-MM-DD"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
:clearable="clearable(item)"
/>
</template>
<!-- 日期时间范围选择 -->
<template v-if="item.searchType == 'datetimerange'">
<el-date-picker
v-model="searchParam[item.prop!]"
v-bind="item.searchProps"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
:clearable="clearable(item)"
/>
</template>
</template>
现在的SearchFormItem组件全部通过vue3内置的component组件来渲染表单项,支持的搜索表单项更多也更灵活:
<!-- 新的 -->
<template>
<component
v-if="column.search?.el && column.prop"
:is="`el-${column.search.el}`"
v-model="searchParam[column.search.key ?? column.prop]"
v-bind="column.search.props"
>
<template v-if="column.search.el === 'select'">
<component
:is="`el-option`"
v-for="(col, index) in columnEnum"
:key="index"
:label="col[fieldNames().label]"
:value="col[fieldNames().value]"
></component>
</template>
</component>
</template>
使用el-table属性和多级表头
通过vue的$attrs,可将绑定到ProTable上的属性(props和emits)直接透传至el-table元素上,具体属性可以参照Element Plus官网
在定义columns时,传入children_属性即可生成多级表头,像这样:
let columns = [
{
label: "基本信息",
prop: "base",
headerAlign: "center",
_children: [
{prop: "username",label: "用户姓名"},
{prop: "gender",label: "性别"},
{prop: "idCard",label: "身份证号"}
]
}
]
自定义表头和单元格
在旧版本中,自定义表头只支持传入renderHeader方法,自定义单元格只支持slot插槽。
现在,经过我的不懈努力,表头支持headerRender(避免与El-Table-Column上的属性重名导致报错)方法和具名插槽(column.prop+'Header')两种方式自定义,单元格支持render方法和具名插槽(column上的prop属性)自定义。
多级表头也同样支持。本来只支持自定义函数,不支持slot的,但是经过我的不懈努力,两者都支持。
搜索表单响应式
在原来的搜索表单中,空间利用率不高,且排版不均匀,特别是在非全屏的情况下特别明显:
现在新的搜索表单项采用grid布局,搜索/重置操作永远放在最后,监听屏幕断点。
你应该不需要去关心它怎么实现的,你只管用就行了
结语
感谢各位小伙伴对GeekerAdmin的支持与帮助!你对我们的支持就是我们最大的动力!
大家一直关心的文档已经在编写之中,此次更新大概率会随着文档一起发布。敬请期待!