123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- import { watch, ref, computed, type Ref } from "vue"
- import type { ILoaderCommon, LoaderLoadType } from "./LoaderCommon";
- export interface ISimplePageListLoader<T, P> extends ILoaderCommon<P> {
- list: Ref<T[]>;
- page: Ref<number>;
- pageSize: Ref<number>;
- next: () => Promise<void>;
- prev: () => Promise<void>;
- total: Ref<number>;
- totalPages: Ref<number>;
- }
- /**
- * 简单分页数据封装。
- *
- * 该封装了分页数据的加载、分页、上一页、下一页等功能。当页码发生变化时,会自动调用加载函数。
- * 简单分页同时只能显示一页数据,重新加载会覆盖之前的数据。
- *
- * 使用示例:
- * ```ts
- * const { data, page, total, loading } = useSimplePagerDataLoader(10, async (page, pageSize) => {
- * const res = await fetch(`/api/data?page=${page}&pageSize=${pageSize}`);
- * const data = await res.json();
- * return {
- * data,
- * page: res.page,
- * total: res.total,
- * };
- * });
- * ```
- *
- * @param pageSize 一页的数量
- * @param loader 加载函数
- * @returns
- */
- export function useSimplePagerDataLoader<T, P = any>(
- _pageSize: number|Ref<number>,
- loader: (page: number, pageSize: number, params?: P) => Promise<{
- list: T[],
- total: number,
- }>) : ISimplePageListLoader<T, P>
- {
- const page = ref(0);
- const pageSize = computed(() => {
- return typeof _pageSize == 'object'? _pageSize.value : _pageSize;
- });
- const list = ref<T[]>([]) as Ref<T[]>;
- const total = ref(0);
- const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
- const loadStatus = ref<LoaderLoadType>('loading');
- const loadError = ref('');
-
- watch(page, async () => {
- await loadData(lastParams, false);
- });
- let lastParams: P | undefined;
- let loading = false;
- async function loadData(params?: P, refresh: boolean = false) {
- if (loading)
- return;
- if (params)
- lastParams = params;
- if (refresh) {
- page.value = 1;
- list.value = [];
- }
- loadStatus.value = 'loading';
- loading = true;
- try {
- const res = (await loader(page.value, pageSize.value, lastParams));
- list.value = list.value.concat(res.list);
- total.value = res.total;
- loadStatus.value = res.list.length > 0 ? 'finished' : 'nomore';
- loadError.value = '';
- loading = false;
- } catch(e) {
- loadError.value = '' + e;
- loadStatus.value = 'error';
- loading = false;
- }
- }
- /**
- * 下一页
- */
- async function next() {
- if (page.value > totalPages.value)
- return;
- page.value++;
- await loadData(lastParams, false);
- }
- /**
- * 上一页
- */
- async function prev() {
- if (page.value <= 1)
- return;
- page.value--;
- await loadData(lastParams, false);
- }
- return {
- loadData,
- next,
- prev,
- /**
- * 数据
- */
- list,
- /**
- * 当前页码
- */
- page,
- pageSize,
- /**
- * 总数据条数
- */
- total,
- /**
- * 总页数
- */
- totalPages,
- loadError,
- loadStatus,
- }
- }
|