为 @corgicoding/web-quick-start
工程模板设定的远程数据下拉组件,基于 @corgicoding-el/data-table
封装。
- 参考阅读
DataTable
的文档使用: 使用文档
-
@corgicoding/web-types
- NormalizedError: 统一错误返回
- NormalizedResponse: 统一接口返回
-
@corgicoding/axios-hook
- useService: 获取当前 axios 实例
-
@corgicoding/permission-hook
- 权限指令方法
-
@corgicoding-el/data-table
- 数据表格
-
@corgicoding-el/data-pagination
- 分页组件
-
@corgicoding-el/custom-dialog
- 弹窗组件,用于自定义列表配置
安装工程到本地,并按需使用或全局使用
- element-plus
- axios
- @vueuse/core
- vue (3.x)
- vue-i18n
- lodash-es
- sortablejs
如果没有以上依赖,工程执行以下命令进行安装
pnpm install element-plus vue @vueuse/core vue-i18n sortablejs axios -S
使用 pnpm
下载
pnpm install @corgicoding-el/data-table-grid -S
假设有个字典列表接口 /test/list
, 返回的内容要求为
/**
* @description 经过清洗的统一给前端业务使用的格式
*/
export interface NormalizedResponse<T = any> {
code: number;
result: T;
message: string;
success: boolean;
timestamp: number;
}
export interface PageReponse {
size: number;
total: number;
pages: number;
current: number;
}
export interface PageParams {
pageNo: number;
pageSize: number;
}
export type TableResponse<T = any> = NormalizedResponse<
{
records: Array<T>;
} & PageReponse
>;
<script setup>
import DataTableGrid from '@corgicoding-el/data-table-grid';
import '@corgicoding-el/data-table-grid/style.css';
// 若不使用国际化翻译则忽略
const { t, locale } = useI18n();
/**
* @description 显示配置
*/
const tableColumns = computed<ColumnType[]>(() => [
{
type: 'selection',
prop: 'selection',
width: 60,
fixed: true
},
{
prop: 'dictName',
width: 120,
// 也可以直接使用硬编码
// name: '字典名称',
name: t('system.dictName')
},
{
prop: 'dictCode',
width: 120,
name: t('system.dictCode')
},
{
prop: 'type',
width: locale.value === 'en' ? 130 : 120,
name: t('system.dictType'),
formatter: row => (row.type === 1 ? '数值' : '字符串')
},
{
prop: 'description',
name: t('system.description'),
width: locale.value === 'en' ? 120 : 80
},
{
prop: 'actions',
slotName: 'actions',
fixed: 'right',
name: t('button.action'),
width: locale.value === 'en' ? 222 : 206,
actions: [
{
key: 'edit',
name: t('button.edit'),
icon: 'edit',
handler: (row, callback) => {
// nowActionRow.value = row;
// actionType.value = 'edit';
// showActionDialog.value = true;
// reload.value = callback;
}
},
{
key: 'settings',
name: t('system.settings'),
icon: 'setting',
handler: (row, callback) => {
// nowActionRow.value = row;
// showSettingDialog.value = true;
// reload.value = callback;
}
},
{
key: 'delete',
icon: 'delete',
name: t('button.delete'),
type: 'danger',
confirmOptions: {
text: t('confirm.commonDelete', [
t('system.dataDict').toLocaleLowerCase()
])
},
handler: async (row, callback) => {
// const response = await deleteDict(row.id);
// ElMessage.success(
// response.data.message instanceof Array
// ? response.data.message.join('\n')
// : response.data.message
// );
callback();
}
}
]
}
]);
/**
* @description 操作配置
*/
const tableActions = computed<ActionType[]>(() => [
{
name: t('button.new'),
key: 'new',
icon: 'plus',
handler: (_, callback) => {
// reload.value = callback;
// nowActionRow.value = {};
// actionType.value = 'new';
// showActionDialog.value = true;
}
},
{
name: t('button.export'),
key: 'export',
icon: 'download',
class: 'ml-2',
handler: rows => {
// const ids = rows instanceof Array ? rows.map(item => item.id) : [];
// exportTableData('/sys/dict/exportXls', {
// queryParams: {
// selections: ids.length > 0 ? ids.join(',') : undefined
// },
// fileName: t('system.dataDict')
// });
}
},
{
name: t('button.batch', [t('button.delete')]),
key: 'batch-delete',
icon: 'delete',
type: 'danger',
class: 'ml-auto',
handler: async (rows, callback) => {
// const ids = rows instanceof Array ? rows.map(item => item.id) : [];
// const response = await batchDeleteDict(ids.join(','));
// ElMessage.success(
// response.data.message instanceof Array
// ? response.data.message.join('\n')
// : response.data.message
// );
callback();
},
// 二次确认配置
confirmOptions: {
text: t('confirm.batchCommon', [
t('button.delete').toLocaleLowerCase(),
t('system.dataDict').toLocaleLowerCase()
]),
checkSelections: true
}
}
]);
</script>
<template>
<DataTableGrid
url="/test/list"
:columns="tableColumns"
:actions="tableActions"
></DataTableGrid>
</template>
表格参数主要由数据引入方式 url
或 data
实现,配置 columns
即可快速实现表格渲染,其余都是表格功能拓展设置。
表格功能拓展设置:
- queryParams
- 接口请求参数
- keepAliveParams
- 固定每次请求携带参数
- height
- 表格高度
- immediateLoad
- 是否初始化请求接口数据
- dataKey
- 接口数据返回,表格读取的key值
- actionTeleportEl
- 头部
action
传送至某个元素进行渲染
- 头部
export interface DataTableGridProps {
url?: string; // 接口
data?: Array<any>; // 数据
loading?: boolean; // 表格loading
columns?: Array<GridColumnType>; // 表格设置
actions: Array<ActionType>; // 头部菜单
queryParams?: any; // 接口额外请求参数
keepAliveParams?: any; // 默认参数
height?: string | number; // 高度
maxHeight?: string | number; // 最大高度
rowKey?: string | ((row: any) => any); // 列表唯一值,tree和保留分页多选时候必传
treeOptions?: {
//树形选项
defaultExpandAll: boolean;
lazy?: boolean;
load?: (row: any, treeNode: any, resolve: any) => void;
props?: {
hasChildren: string;
children: string;
};
};
paginationOptions?: PaginationProps; // el-pagination 原生 props
paginationEvents?: PaginationEmits; // el-pagination 原生 emits
defaultPaginaiton?: PaginationSetting; // 默认分页设置
/**
* @deprecated 后续使用 paginationOptions 代替
*/
paginaitonLayout?: string;
/**
* @deprecated 后续使用 tableAttrs | tableStyles 代替
*/
stripe?: boolean; // 斑马纹
dataKey?: string | ResponseFunc; // 返回接口的 data 对应 key
resultKey?: string | ResponseFunc; // 返回接口的 result 对应 key
defaultSelections?: Array<any>; // 默认选中的行
noMutiple?: boolean; // 非多选
hasHeader?: boolean; // 是否有头部
hasFooter?: boolean; // 是否有底部
hasPagination?: boolean; // 是否有分页
tableAttrs?: TableProps<any>; // 同 DataTable,el-table 原生参数
eventMethods?: any; // 同 DataTable,el-table 原生事件
immediateLoad?: boolean; // 是否一开始就加载接口
resetOnExecute?: boolean; // 刷新是否重置数据为空
actionTeleportEl?: HTMLDivElement; // 头部菜单部署元素
// 接管api处理方法
hackApiHandler?: (
url?: string,
page?: number,
pageSize?: number
) => TableApiReturn;
// 表格自定义配置修改
dgId?: string | number;
// 是否有表格自定义配置功能
hasColConfig?: boolean;
}
通过 columns
配置表格显示的列如何显示
export interface ColumnType {
prop: string; // 表头返回字段参数
name?: string; // 表头显示名称
type?: string | 'selection'; // 可以设置为 selection
width?: number | string; // 宽度占比
fixed?: boolean | string; // 固定位置
align?: string; // 文本居中布局
slotName?: string; // 添加插槽名自定义
formatter?: (row?: any, column?: any, cellValue?: any, index?: number) => any; // 格式化显示数据
renderHeader?: (column?: any) => any; // 表头自定义渲染
selectable?: (row?: any, index?: number) => any; // 若 type 为 selection 则操作是否可选
sortable?: boolean | 'custom'; // 排序
columnOptions?: any; // el-table-column 列选项
eventOptions?: any; // el-table-column 事件选项
hidden?: boolean; // 隐藏
sort?: number; // 排序
children?: Array<ColumnType>; // 是否有子集
}
export interface GridColumnType extends ColumnType {
actions?: Array<ActionType>;
children?: Array<GridColumnType>;
}
const Emits = defineEmits([
'update:queryParams', // 请求参数更新
'selection-change', // 表格选择更新
'key-selection-change', // 表格选择项 - key更新
'page-selection-change', // 表格选择项 - 分页选中更新
'data-change', // 数据变化
'loading' // loading监听
]);
defineExpose({
elRef, // el-table
tableColumns, // 实际显示列表配置
pending, // 是否正在请求
tableData, // 当前显示列表数据
sortQueryParams, // 排序请求参数对象
keySelections, // 当前选中key
totalKeySelections, // 分页 - 当前选中key
loadTableData, // 加载列表数据方法
resetTableData, // 重置列表数据
resetKeySelection // 重置选中数据
});
案例如下
<script setup>
import DataTableGrid from '@corgicoding-el/data-table-grid';
// import '@corgicoding-el/data-table-grid/style.css';
// ...
</script>
<template>
<DataTableGrid />
</template>
在 main.ts
引入
import DataTableGrid from '@corgicoding-el/data-table-grid';
// import '@corgicoding-el/data-table-grid/style.css';
app.use(DataTableGrid);
根据模板的接口习惯, 由于列表接口一般为 records
包在 res.data.result
内,且传参为 pageSize=15&page=1
时,能返回所有列表数据。
<script setup></script>
<template>
<DataTableGrid
url="/test/list"
:columns="tableColumns"
:actions="tableActions"
></DataTableGrid>
</template>
待补充
查看 DataTable
使用文档
待补充
待补充
待补充
待补充
待补充