import { computed, ref, watch, type Ref } from 'vue' /** 默认每页条数 */ export const DEFAULT_PAGE_SIZE = 10 /** 可选每页条数 */ export const PAGE_SIZES = [10, 20, 50] /** * 前端列表分页(对接真实接口前先对本地数组切片) * @param source 完整列表 ref,或返回列表的 getter(适合 computed) */ function asArray(value: unknown): T[] { if (Array.isArray(value)) return value if (value && typeof value === 'object') { const list = (value as { list?: unknown }).list if (Array.isArray(list)) return list as T[] } return [] } export function useClientPagination( source: Ref | (() => T[]), options?: { pageSize?: number }, ) { const page = ref(1) const pageSize = ref(options?.pageSize ?? DEFAULT_PAGE_SIZE) const sourceList = computed(() => asArray(typeof source === 'function' ? source() : source.value), ) const total = computed(() => sourceList.value.length) const pageCount = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value) || 1), ) const pagedList = computed(() => { const start = (page.value - 1) * pageSize.value return sourceList.value.slice(start, start + pageSize.value) }) function resetPage() { page.value = 1 } function goFirst() { page.value = 1 } function goLast() { page.value = pageCount.value } // 数据量或每页条数变化时,纠正越界页码 watch([total, pageSize], () => { if (page.value > pageCount.value) { page.value = pageCount.value } }) return { page, pageSize, total, pageCount, pagedList, resetPage, goFirst, goLast, } }