53 lines
1.2 KiB
TypeScript
53 lines
1.2 KiB
TypeScript
import { ref, type Ref } from 'vue'
|
|
|
|
interface PaginatedResult<T> {
|
|
items: T[]
|
|
total: number
|
|
}
|
|
|
|
interface AdminPaginatedTableOptions<T> {
|
|
fetchFn: (page: number, pageSize: number) => Promise<PaginatedResult<T>>
|
|
defaultPageSize?: number
|
|
immediate?: boolean
|
|
}
|
|
|
|
interface AdminPaginatedTableResult<T> {
|
|
loading: Ref<boolean>
|
|
data: Ref<T[]>
|
|
total: Ref<number>
|
|
currentPage: Ref<number>
|
|
currentPageSize: Ref<number>
|
|
load: () => Promise<void>
|
|
handleSizeChange: () => void
|
|
}
|
|
|
|
export function useAdminPaginatedTable<T>(options: AdminPaginatedTableOptions<T>): AdminPaginatedTableResult<T> {
|
|
const loading = ref(false)
|
|
const data = ref<T[]>([]) as Ref<T[]>
|
|
const total = ref(0)
|
|
const currentPage = ref(1)
|
|
const currentPageSize = ref(options.defaultPageSize || 20)
|
|
|
|
async function load() {
|
|
loading.value = true
|
|
try {
|
|
const result = await options.fetchFn(currentPage.value, currentPageSize.value)
|
|
data.value = result.items
|
|
total.value = result.total
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
function handleSizeChange() {
|
|
currentPage.value = 1
|
|
load()
|
|
}
|
|
|
|
if (options.immediate !== false) {
|
|
load()
|
|
}
|
|
|
|
return { loading, data, total, currentPage, currentPageSize, load, handleSizeChange }
|
|
}
|