diff --git a/packages/core/index.ts b/packages/core/index.ts index 334030f..60c02a9 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -5,3 +5,4 @@ export * from './useProgress' export * from './useCalendar' export * from './useCountdown' export * from './useUpload' +export * from './usePagination' diff --git a/packages/core/usePagination/index.ts b/packages/core/usePagination/index.ts index 4d02fcb..f7225a8 100644 --- a/packages/core/usePagination/index.ts +++ b/packages/core/usePagination/index.ts @@ -1,9 +1,130 @@ -interface UsePaginationOption { +import { ref, computed, type ComputedRef, type Ref } from 'vue' +interface PageItem { + value: number + isCurrent: boolean + type: 'page' | 'ellipsis' } -interface usePaginationReturn { +interface UsePaginationOption { + total: number + pageSize?: number + currentPage?: number + maxPageCount?: number + ellipsis?: boolean +} +interface UsePaginationReturn { + currentPage: Ref + isFirstPage: ComputedRef + isLastPage: ComputedRef + pages: ComputedRef + totalPage: ComputedRef + gotoPage: (page: number) => void + nextPage: () => void + previousPage: () => void + setPageSize: (pageSize: number) => void + gotoFirstPage: () => void + gotoLastPage: () => void } -export const usePagination = (options: UsePaginationOption): usePaginationReturn => { } \ No newline at end of file +export const usePagination = ( + options: UsePaginationOption +): UsePaginationReturn => { + const { total, ellipsis = false } = options + + const currentPage = ref(options.currentPage || 1) + const pageSize = ref(options.pageSize || 10) + const isFirstPage = computed(() => currentPage.value === 1) + const totalPage = computed(() => Math.ceil(total / pageSize.value)) + const maxPageCount = + (options.maxPageCount || 5) > totalPage.value + ? totalPage.value + : options.maxPageCount || 5 + const isLastPage = computed(() => currentPage.value === totalPage.value) + const pages = computed(() => + Array.from({ length: maxPageCount }, (_, index) => { + if (!ellipsis) { + return { + text: index + 1, + value: index + 1, + isCurrent: index + 1 === currentPage.value, + type: 'page', + } + } + if (maxPageCount % 2 === 0) { + if ( + index + 1 <= maxPageCount / 2 || + totalPage.value - (index + 1) < maxPageCount / 2 + ) { + return { + text: index + 1, + value: index + 1, + isCurrent: index + 1 === currentPage.value, + type: 'page', + } + } + return { + text: '...', + value: 0, + isCurrent: false, + type: 'ellipsis', + } + } + if (Math.floor(maxPageCount / 2) + 1 === index + 1) { + return { + text: '...', + value: 0, + isCurrent: false, + type: 'ellipsis', + } + } + return { + text: index + 1, + value: index + 1, + isCurrent: index + 1 === currentPage.value, + type: 'page', + } + }) + ) + + const gotoPage = (page: number) => { + currentPage.value = page + } + + const nextPage = () => { + if (currentPage.value === totalPage.value) return + currentPage.value += 1 + } + + const previousPage = () => { + if (currentPage.value === 1) return + currentPage.value -= 1 + } + + const setPageSize = (newPageSize: number) => { + pageSize.value = newPageSize + } + + const gotoFirstPage = () => { + currentPage.value = 1 + } + + const gotoLastPage = () => { + currentPage.value = totalPage.value + } + + return { + currentPage, + isFirstPage, + isLastPage, + totalPage, + pages, + gotoPage, + nextPage, + previousPage, + setPageSize, + gotoFirstPage, + gotoLastPage, + } +} diff --git a/src/App.vue b/src/App.vue index 25e2539..d95bc39 100644 --- a/src/App.vue +++ b/src/App.vue @@ -4,7 +4,8 @@ // import UseProgress from './demo/UseProgress.vue' // import UseCalendar from './demo/UseCalendar.vue' // import UseCountdown from './demo/UseCountdown.vue' -import UseUpload from './demo/UseUpload.vue' +// import UseUpload from './demo/UseUpload.vue' +import UsePagination from './demo/UsePagination.vue' diff --git a/src/demo/UsePagination.vue b/src/demo/UsePagination.vue new file mode 100644 index 0000000..e870277 --- /dev/null +++ b/src/demo/UsePagination.vue @@ -0,0 +1,93 @@ + + +