import useState from '../../_util/hooks/useState'; import type { Ref } from 'vue'; import { computed } from 'vue'; import type { PaginationProps } from '../../pagination'; import type { TablePaginationConfig } from '../interface'; export const DEFAULT_PAGE_SIZE = 10; export function getPaginationParam( pagination: TablePaginationConfig | boolean | undefined, mergedPagination: TablePaginationConfig, ) { const param: any = { current: mergedPagination.current, pageSize: mergedPagination.pageSize, }; const paginationObj = pagination && typeof pagination === 'object' ? pagination : {}; Object.keys(paginationObj).forEach(pageProp => { const value = (mergedPagination as any)[pageProp]; if (typeof value !== 'function') { param[pageProp] = value; } }); return param; } function extendsObject(...list: T[]) { const result: T = {} as T; list.forEach(obj => { if (obj) { Object.keys(obj).forEach(key => { const val = (obj as any)[key]; if (val !== undefined) { (result as any)[key] = val; } }); } }); return result; } export default function usePagination( totalRef: Ref, paginationRef: Ref, onChange: (current: number, pageSize: number) => void, ): [Ref, () => void] { const pagination = computed(() => paginationRef.value && typeof paginationRef.value === 'object' ? paginationRef.value : {}, ); const paginationTotal = computed(() => pagination.value.total || 0); const [innerPagination, setInnerPagination] = useState<{ current?: number; pageSize?: number; }>(() => ({ current: 'defaultCurrent' in pagination.value ? pagination.value.defaultCurrent : 1, pageSize: 'defaultPageSize' in pagination.value ? pagination.value.defaultPageSize : DEFAULT_PAGE_SIZE, })); // ============ Basic Pagination Config ============ const mergedPagination = computed(() => { const mP = extendsObject>( innerPagination.value, pagination.value, { total: paginationTotal.value > 0 ? paginationTotal.value : totalRef.value, }, ); // Reset `current` if data length or pageSize changed const maxPage = Math.ceil((paginationTotal.value || totalRef.value) / mP.pageSize!); if (mP.current! > maxPage) { // Prevent a maximum page count of 0 mP.current = maxPage || 1; } return mP; }); const refreshPagination = (current = 1, pageSize?: number) => { if (pagination.value === false) return; setInnerPagination({ current, pageSize: pageSize || mergedPagination.value.pageSize, }); }; const onInternalChange: PaginationProps['onChange'] = (current, pageSize) => { if (pagination.value) { pagination.value.onChange?.(current, pageSize); } refreshPagination(current, pageSize); onChange(current, pageSize || mergedPagination.value.pageSize); }; return [ computed(() => { return pagination.value === false ? {} : { ...mergedPagination.value, onChange: onInternalChange }; }), refreshPagination, ]; }