Skip to content

Commit

Permalink
refactor(projects): update useTable
Browse files Browse the repository at this point in the history
  • Loading branch information
honghuangdc committed Apr 4, 2023
1 parent db62959 commit 211ae1f
Showing 1 changed file with 105 additions and 43 deletions.
148 changes: 105 additions & 43 deletions src/hooks/business/use-table.ts
Original file line number Diff line number Diff line change
@@ -1,89 +1,151 @@
import { ref, reactive } from 'vue';
import type { Ref } from 'vue';
import type { DataTableBaseColumn, DataTableSelectionColumn, DataTableExpandColumn, PaginationProps } from 'naive-ui';
import type { MaybeComputedRef } from '@vueuse/core';
import type { TableColumnGroup, InternalRowData } from 'naive-ui/es/data-table/src/interface';
import { useLoadingEmpty } from '../common';

/**
* 表格的列
* 表格分页参数
*/
type DataTableColumn<T = InternalRowData> =
| (Omit<TableColumnGroup<T>, 'key'> & { key: keyof T })
| (Omit<DataTableBaseColumn<T>, 'key'> & { key: keyof T })
| DataTableSelectionColumn<T>
| DataTableExpandColumn<T>;
type PaginationParams = Pick<PaginationProps, 'page' | 'pageSize'>;

/**
* 表格分页参数
* 表格请求接口的参数
*/
type TablePaginationParams = Pick<PaginationProps, 'page' | 'pageSize'>;
type ApiParams = Record<string, unknown> & PaginationParams;

/**
* 表格接口的请求参数
* 表格请求接口的结果
* @description 这里用属性list来表示后端接口返回的表格数据
*/
type TableApiParams = Record<string, unknown> & TablePaginationParams;
type ApiData<TableData = Record<string, unknown>> = Record<string, unknown> & { list: TableData[] };

/**
* 表格接口的请求数据
* 表格接口的请求函数
*/
type ApiFn<Params = ApiParams, TableData = Record<string, unknown>> = (
params: Params
) => Promise<Service.RequestResult<ApiData<TableData>>>;

/**
* 表格接口请求后转换后的数据
*/
type TableApiData<T = InternalRowData> = {
data: T[];
type TransformedTableData<TableData = Record<string, unknown>> = {
data: TableData[];
pageNum: number;
pageSize: number;
total: number;
};

/**
* 表格接口的请求函数
* 表格的列
*/
type TableApiFn<P extends TableApiParams, T extends InternalRowData> = (
params: P
) => Promise<Service.SuccessResult<TableApiData<T>>>;

export function useNaiveTable<TableData extends InternalRowData, P extends TableApiParams>(
apiFn: TableApiFn<P, TableData>,
apiParams: P,
columns: MaybeComputedRef<DataTableColumn<TableData>[]>
) {
const { loading, startLoading, endLoading, empty, setEmpty } = useLoadingEmpty();
type DataTableColumn<T = InternalRowData> =
| (Omit<TableColumnGroup<T>, 'key'> & { key: keyof T })
| (Omit<DataTableBaseColumn<T>, 'key'> & { key: keyof T })
| DataTableSelectionColumn<T>
| DataTableExpandColumn<T>;

const tableData: Ref<TableData[]> = ref([]);
/**
* 表格数据转换器
* @description 将不同接口的表格数据转换成统一的类型
*/
type Transformer<TableData = Record<string, unknown>> = (
apiData: ApiData<TableData>
) => TransformedTableData<TableData>;

async function getTableData(paginationParams?: TablePaginationParams) {
startLoading();
type TableParams<TableData = Record<string, unknown>, Params = ApiParams> = {
apiFn: ApiFn<Params, TableData>;
apiParams: Params;
transformer: Transformer<TableData>;
columns: DataTableColumn<TableData>[];
pagination?: PaginationProps;
};

const params = { ...apiParams, ...paginationParams };
export function useTable<TableData extends Record<string, unknown>, Params extends ApiParams>(
params: TableParams<TableData, Params>,
immediate = true
) {
const { loading, startLoading, endLoading, empty, setEmpty } = useLoadingEmpty();
const data: Ref<TableData[]> = ref([]);

const { data } = await apiFn(params);
if (data) {
tableData.value = data.data;
function updateData(update: TableData[]) {
data.value = update;
}

setEmpty(data.data.length === 0);
}
endLoading();
let dataSource: TableData[] = [];
function setDataSource(source: TableData[]) {
dataSource = source;
}

const pagination: PaginationProps = reactive({
page: 1,
pageSize: 10,
showSizePicker: true,
pageSizes: [10, 15, 20, 25, 30],
function resetData() {
data.value = dataSource;
}

const columns = ref(params.columns) as Ref<DataTableColumn<TableData>[]>;

const pagination = reactive({
...getPagination(params.pagination),
onChange: (page: number) => {
pagination.page = page;
},
onUpdatePageSize: (pageSize: number) => {
pagination.pageSize = pageSize;
pagination.page = 1;
}
});
}) as PaginationProps;

function updatePagination(update: Partial<PaginationProps>) {
Object.assign(pagination, update);
}

async function getData() {
const apiParams: Params = { ...params.apiParams };
apiParams.page = apiParams.page || pagination.page;
apiParams.pageSize = apiParams.pageSize || pagination.pageSize;

startLoading();
const { data: apiData } = await params.apiFn(apiParams);

if (apiData) {
const transformedData = params.transformer(apiData);

updateData(transformedData.data);

setDataSource(transformedData.data);

setEmpty(transformedData.data.length === 0);

updatePagination({ page: transformedData.pageNum, pageSize: transformedData.pageSize });
}

endLoading();
}

if (immediate) {
getData();
}

return {
tableData,
data,
columns,
loading,
empty,
pagination,
start: getTableData
getData,
updateData,
resetData
};
}

function getPagination(pagination?: Partial<PaginationProps>) {
const defaultPagination: Partial<PaginationProps> = {
page: 1,
pageSize: 10,
showSizePicker: true,
pageSizes: [10, 15, 20, 25, 30]
};
Object.assign(defaultPagination, pagination);

return defaultPagination;
}

1 comment on commit 211ae1f

@vercel
Copy link

@vercel vercel bot commented on 211ae1f Apr 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.