| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- import { watch, ref, computed, type Ref } from "vue"
- import type { ILoaderCommon, LoaderLoadType } from "./LoaderCommon";
- import { formatError } from "~/components/error/ErrorReporterIs";
- export interface ISimplePageListLoader<T, P> extends ILoaderCommon<P> {
- list: Ref<T[]>;
- page: 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<{
- data: T[],
- total: number,
- }>) : ISimplePageListLoader<T, P>
- {
- const page = ref(0);
- const list = ref<T[]>([]) as Ref<T[]>;
- const total = ref(0);
- const totalPages = computed(() => Math.ceil(total.value / getPageSize()));
- const loadStatus = ref<LoaderLoadType>('loading');
- const loadError = ref('');
- function getPageSize() {
- return typeof pageSize == 'object'? pageSize.value : pageSize;
- }
-
- 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, getPageSize(), lastParams));
- list.value = list.value.concat(res.data);
- total.value = res.total;
- loadStatus.value = res.data.length > 0 ? 'finished' : 'nomore';
- loadError.value = '';
- loading = false;
- } catch(e) {
- loadError.value = '' + e;
- loadStatus.value = 'error';
- loading = false;
- }
- }
- /**
- * 下一页
- */
- async function next() {
- if (page.value > total.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,
- /**
- * 总数据条数
- */
- total,
- /**
- * 总页数
- */
- totalPages,
- loadError,
- loadStatus,
- }
- }
- export async function useSSrSimplePagerDataLoader<T, P = any>(
- name: string,
- startPage: number,
- pageSize: number|Ref<number>,
- loader: (page: number, pageSize: number, params?: P) => Promise<{
- data: T[],
- total: number,
- }>,
- params : P|undefined = undefined,
- ) : Promise<ISimplePageListLoader<T, P>>
- {
- const route = useRoute();
- let lastParams: P | undefined = params;
- const page = ref(startPage);
- const {
- data,
- error
- } = (await useAsyncData(route.fullPath + '/' + name, () => loader(page.value, getPageSize(), lastParams)))
- const list = ref<T[]>([]) as Ref<T[]>;
- const total = ref(0);
- const totalPages = computed(() => Math.ceil(total.value / getPageSize()));
- const loadStatus = ref<LoaderLoadType>('finished');
- const loadError = ref('');
- if (error.value) {
- loadError.value = '' + formatError (error.value);
- loadStatus.value = 'error';
- } else if (data.value) {
- list.value = data.value.data as any;
- total.value = data.value.total as any;
- loadError.value = '';
- loadStatus.value = 'finished';
- }
- function getPageSize() {
- return typeof pageSize == 'object'? pageSize.value : pageSize;
- }
- watch(page, async () => {
- await loadData(lastParams, false);
- });
- 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, getPageSize(), lastParams));
- list.value = list.value.concat(res.data);
- total.value = res.total;
- loadStatus.value = list.value.length > 0 ? 'finished' : 'nomore';
- loadError.value = '';
- loading = false;
- } catch(e) {
- loadError.value = '' + formatError(e);
- loadStatus.value = 'error';
- loading = false;
- }
- }
- /**
- * 下一页
- */
- async function next() {
- if (page.value > total.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: list as any as Ref<T[]>,
- page,
- total,
- totalPages,
- loadError,
- loadStatus,
- }
- }
|