Files
lingji-work-fe/src/hooks/table-hooks.ts
2025-06-16 14:42:26 +08:00

173 lines
4.2 KiB
TypeScript

/*
* @Author: 田鑫
* @Date: 2023-02-16 15:02:51
* @LastEditors: 田鑫
* @LastEditTime: 2023-03-09 11:20:59
* @Description: table-hooks
*/
import type { PaginationProps, TableBorder, TableColumnData, TableData, TableRowSelection } from '@arco-design/web-vue';
type Size = 'mini' | 'small' | 'medium' | 'large';
interface IDefaultProps {
/** 是否显示边框 */
bordered?: TableBorder;
/** 是否显示选中效果 */
hoverable?: boolean;
/** 表格的大小 */
size?: Size;
/** 是否允许调整列宽 */
'column-resizable'?: boolean;
/** 是否为加载中状态 */
loading?: boolean;
/** 分页参数 */
pagination?: PaginationProps;
/** table数据类型 */
data?: any[];
/** 表头参数 */
columns?: TableColumnData[];
/** 表格行 key 的取值字段 */
'row-key'?: string;
/** 表格的行选择器配置 */
'row-selection'?: TableRowSelection;
'selected-keys'?: (string | number)[];
[x: string]: any;
}
interface IPagination {
/** 当前页数 */
current?: number;
/** 总页数默认是0条 */
total?: number;
}
interface ITableResponse<T> {
current?: number;
records?: T[];
size?: number;
total?: number;
[x: string]: any;
}
type GetListFunc<T> = (v: object) => Promise<ITableResponse<T>>;
export default function useTableProps<T>(loadListFunc: GetListFunc<T>) {
const defaultProps: IDefaultProps = {
bordered: { cell: true },
size: 'large',
'column-resizable': true,
loading: true,
data: [] as any[],
pagination: {
current: 1,
pageSize: 20,
total: 0,
showPageSize: true,
showTotal: true,
},
hoverable: false,
columns: [],
};
//* 属性组
const propsRes = reactive<IDefaultProps>(defaultProps);
//* 设置请求参数,如果出了分页参数还有搜索参数,在模板页面调用此方法,可以加入参数
const loadListParams = reactive<object>({
page: 1,
size: 20,
});
/**
* 单独设置默认属性
* @param params
*/
const setProps = (params: IDefaultProps) => {
if (Object.keys(params).length > 0) {
Object.assign(defaultProps, params);
}
};
/**
* 设置表头数据
* @param columns
*/
const setColumns = (columns: TableColumnData[]) => {
propsRes.columns = columns;
};
/**
* 设置loading
* @param status
*/
const setLoading = (status: boolean) => {
propsRes.loading = status;
};
/**
* 设置分页
* @param param0
*/
const setPagination = ({ current, total }: IPagination) => {
propsRes.pagination!.current = current;
total && (propsRes.pagination!.total = total);
Object.assign(loadListParams, { page: current });
};
/**
* 设置列表请求参数
* @param params
*/
const setLoadListParams = <R>(params?: R) => {
Object.assign(loadListParams, params);
};
/**
* 加载列表
* @returns
*/
const loadTableData = async (resetPageIndex = false) => {
if (resetPageIndex) {
setPagination({ current: 1 });
}
setLoading(true);
try {
const resData = await loadListFunc({
...loadListParams,
});
console.log(resData);
const response = resData as ITableResponse<T>;
propsRes.data = response.records;
setPagination({
current: response.current,
total: response.total,
});
setLoading(false);
return resData;
} catch (error) {
setLoading(false);
return [];
}
};
// 事件触发组
const propsEvent = reactive({
// 排序触发
sorterChange: (dataIndex: string, direction: string) => {
console.log(dataIndex, direction);
},
// 分页触发
pageChange: (current: number) => {
setPagination({ current });
loadTableData();
},
// 修改每页显示条数
pageSizeChange: (size: number) => {
propsRes.pagination!.pageSize = size;
Object.assign(loadListParams, { size });
loadTableData();
},
selectionChange: (rowKeys: (string | number)[]) => {
propsRes['selected-keys'] = rowKeys;
},
});
return {
propsRes,
propsEvent,
loadListParams,
setProps,
setColumns,
setLoading,
setPagination,
loadTableData,
setLoadListParams,
};
}