import { ref, Ref } from "vue"; // 分页器的可选参数 export interface PagerOptions { current?: number; size?: number; total?: number; } // Loader 的参数 export interface LoaderParams { current: number; size: number; } // Loader 的返回值 export interface LoaderRes { current?: number; size?: number; total: number; records: Array; } // Loader export type LoaderTyp = (params: LoaderParams) => Promise>; const PAGER_DEF_VALUE = () => ({ PAGE_INDEX: 0, PAGE_SIZE: 10, TOTAL: -1, RECORDS: [] }); export enum PagerState { // 分页器处于初始状态 INIT, // 闲置 IDLE, // 加载数据中 LOADING, // 没有更多数据 NO_MORE, // 网络异常 NETWORK_ERR } // 分页器 export class Pager { current = PAGER_DEF_VALUE().PAGE_INDEX; size = PAGER_DEF_VALUE().PAGE_SIZE; total = PAGER_DEF_VALUE().TOTAL; records: Ref> = ref(PAGER_DEF_VALUE().RECORDS); loader: LoaderTyp; // 状态 state: Ref = ref(PagerState.INIT); constructor(loader: LoaderTyp, options?: PagerOptions) { this.loader = loader; const pageDef = PAGER_DEF_VALUE(); this.current = options?.current || pageDef.PAGE_INDEX; this.size = options?.size || pageDef.PAGE_SIZE; this.total = options?.total || pageDef.TOTAL; this.records.value = pageDef.RECORDS; } // 是否还存在数据 isNoMore = () => this.total > 0 && this.total <= this.current * this.size; // 无数据 // isEmpty = this.state.value === PagerState.IDLE && this.records.value.length <= 0 // 获取记录列表 #_getNextRecodes = async (): Promise> => { const res = await this.loader({ current: this.current + 1, size: this.size }); this.current += 1; this.total = res.total || 0; return res.records || []; }; getNextRecodes = async (): Promise> => { if (this.state.value === PagerState.LOADING) { return []; } if (this.isNoMore()) { this.state.value = PagerState.NO_MORE; return []; } this.state.value = PagerState.LOADING; try { const resp: Array = await this.#_getNextRecodes(); return resp; } finally { this.state.value = PagerState.IDLE; } }; // 加载下一页数据 nextPage = async () => { const records = await this.getNextRecodes(); this.records.value.push(...records); return this.records; }; // 加载更多 loadMore = this.nextPage; // 重置数据 reInit = (options?: PagerOptions) => { const pageDef = PAGER_DEF_VALUE(); this.current = options?.current || pageDef.PAGE_INDEX; this.total = options?.total || pageDef.TOTAL; this.state.value = PagerState.INIT; }; // 重新加载 reload = async () => { if (this.state.value === PagerState.LOADING || this.state.value === PagerState.NO_MORE) { return; } this.reInit(); const records = await this.getNextRecodes(); this.records.value = records; return this.records; }; // 刷新 refresh = this.reload; async refreshWithChangeLoader(loader?: LoaderTyp) { loader && (this.loader = loader); await this.reload(); } } export default Pager;