mirror of https://github.com/halo-dev/halo-admin
parent
c4056c5b72
commit
668c678714
|
@ -2,8 +2,8 @@
|
|||
<Story :init-state="initState" title="Pagination">
|
||||
<template #default="{ state }">
|
||||
<VPagination
|
||||
:page="state.page"
|
||||
:size="state.size"
|
||||
v-model:page="state.page"
|
||||
v-model:size="state.size"
|
||||
:total="state.total"
|
||||
></VPagination>
|
||||
</template>
|
||||
|
|
|
@ -1,24 +1,32 @@
|
|||
<script lang="ts" setup>
|
||||
import { UseOffsetPagination } from "@vueuse/components";
|
||||
import { IconArrowLeft, IconArrowRight } from "../../icons/icons";
|
||||
import { ref, toRefs, watch } from "vue";
|
||||
import { ref, toRefs, watch, watchEffect } from "vue";
|
||||
import { useOffsetPagination } from "@vueuse/core";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
page?: number;
|
||||
size?: number;
|
||||
total?: number;
|
||||
sizeOptions?: number[];
|
||||
}>(),
|
||||
{
|
||||
page: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
sizeOptions: () => [10],
|
||||
}
|
||||
);
|
||||
|
||||
const { page, size, total } = toRefs(props);
|
||||
const page = ref(props.page);
|
||||
const size = ref(props.size);
|
||||
const total = ref(props.total);
|
||||
|
||||
const key = ref(Math.random());
|
||||
watch([() => props.page, () => props.size, () => props.total], () => {
|
||||
page.value = props.page;
|
||||
size.value = props.size;
|
||||
total.value = props.total;
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "update:page", page: number): void;
|
||||
|
@ -33,81 +41,97 @@ const onPageChange = ({
|
|||
currentPage: number;
|
||||
currentPageSize: number;
|
||||
}) => {
|
||||
emit("update:page", currentPage);
|
||||
emit("update:size", currentPageSize);
|
||||
emit("change", {
|
||||
page: currentPage,
|
||||
size: currentPageSize,
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => total?.value,
|
||||
() => {
|
||||
key.value = Math.random();
|
||||
}
|
||||
);
|
||||
const {
|
||||
currentPage,
|
||||
currentPageSize,
|
||||
pageCount,
|
||||
isFirstPage,
|
||||
isLastPage,
|
||||
prev,
|
||||
next,
|
||||
} = useOffsetPagination({
|
||||
total: total,
|
||||
page: page,
|
||||
pageSize: size,
|
||||
onPageChange: onPageChange,
|
||||
onPageSizeChange: onPageChange,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<UseOffsetPagination
|
||||
:key="key"
|
||||
v-slot="{ currentPage, next, prev, pageCount }"
|
||||
:page="page"
|
||||
:page-size="size"
|
||||
:total="total"
|
||||
@page-change="onPageChange"
|
||||
@page-size-change="onPageChange"
|
||||
>
|
||||
<div class="bg-white flex items-center justify-between">
|
||||
<div class="flex-1 flex justify-between sm:!hidden items-center">
|
||||
<span
|
||||
class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 cursor-pointer"
|
||||
<div class="bg-white flex items-center justify-between">
|
||||
<div class="flex-1 flex justify-between sm:!hidden items-center">
|
||||
<span
|
||||
class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 cursor-pointer"
|
||||
@click="prev"
|
||||
>
|
||||
<IconArrowLeft />
|
||||
</span>
|
||||
<span class="text-sm text-gray-500">
|
||||
{{ currentPage }} / {{ pageCount }}
|
||||
</span>
|
||||
<span
|
||||
class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 cursor-pointer"
|
||||
@click="next"
|
||||
>
|
||||
<IconArrowRight />
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center items-center gap-2">
|
||||
<nav
|
||||
aria-label="Pagination"
|
||||
class="relative z-0 inline-flex rounded-base shadow-sm -space-x-px"
|
||||
>
|
||||
<button
|
||||
class="relative h-8 outline-none inline-flex items-center px-2 py-1.5 rounded-l-base border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50 cursor-pointer disabled:cursor-not-allowed"
|
||||
:disabled="isFirstPage"
|
||||
@click="prev"
|
||||
>
|
||||
<IconArrowLeft />
|
||||
</span>
|
||||
<span class="text-sm text-gray-500">
|
||||
{{ currentPage }} / {{ pageCount }}
|
||||
</span>
|
||||
<span
|
||||
class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 cursor-pointer"
|
||||
</button>
|
||||
<button
|
||||
class="relative h-8 outline-none inline-flex items-center px-2 py-1.5 rounded-r-base border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50 cursor-pointer disabled:cursor-not-allowed"
|
||||
:disabled="isLastPage"
|
||||
@click="next"
|
||||
>
|
||||
<IconArrowRight />
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center">
|
||||
<nav
|
||||
aria-label="Pagination"
|
||||
class="relative z-0 inline-flex rounded-base shadow-sm -space-x-px"
|
||||
</button>
|
||||
</nav>
|
||||
<div class="inline-flex items-center gap-2">
|
||||
<select
|
||||
v-model="currentPage"
|
||||
:disabled="pageCount === 0"
|
||||
class="h-8 border outline-none rounded-base px-2 text-gray-800 text-sm border-gray-300"
|
||||
>
|
||||
<span
|
||||
class="relative inline-flex items-center px-2 py-2 rounded-l-[4px] border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50 cursor-pointer"
|
||||
@click="prev"
|
||||
<option v-if="pageCount === 0" :value="0">0 / 0</option>
|
||||
<option v-for="i in pageCount" :key="i" :value="i">
|
||||
{{ i }} / {{ pageCount }}
|
||||
</option>
|
||||
</select>
|
||||
<span class="text-sm text-gray-500">页</span>
|
||||
</div>
|
||||
<div class="inline-flex items-center gap-2">
|
||||
<select
|
||||
v-model="currentPageSize"
|
||||
class="h-8 border outline-none rounded-base px-2 text-gray-800 text-sm border-gray-300"
|
||||
>
|
||||
<option
|
||||
v-for="(sizeOption, index) in sizeOptions"
|
||||
:key="index"
|
||||
:value="sizeOption"
|
||||
>
|
||||
<IconArrowLeft />
|
||||
</span>
|
||||
<span
|
||||
v-for="i in pageCount"
|
||||
:key="i"
|
||||
:class="{
|
||||
'z-10 bg-primary/1 border-primary text-primary':
|
||||
i === currentPage,
|
||||
'bg-white border-gray-300 text-gray-500 hover:bg-gray-50':
|
||||
i !== currentPage,
|
||||
}"
|
||||
aria-current="page"
|
||||
class="relative inline-flex items-center px-4 py-2 border text-sm font-medium cursor-pointer select-none"
|
||||
@click="currentPage.value = i"
|
||||
>
|
||||
{{ i }}
|
||||
</span>
|
||||
<span
|
||||
class="relative inline-flex items-center px-2 py-2 rounded-r-[4px] border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50 cursor-pointer"
|
||||
@click="next"
|
||||
>
|
||||
<IconArrowRight />
|
||||
</span>
|
||||
</nav>
|
||||
{{ sizeOption }}
|
||||
</option>
|
||||
</select>
|
||||
<span class="text-sm text-gray-500">条 / 页</span>
|
||||
</div>
|
||||
</div>
|
||||
</UseOffsetPagination>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -690,6 +690,7 @@ onMounted(() => {
|
|||
:page="attachments.page"
|
||||
:size="attachments.size"
|
||||
:total="attachments.total"
|
||||
:size-options="[60, 120, 200]"
|
||||
@change="handlePaginationChange"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -165,6 +165,7 @@ await handleFetchAttachments();
|
|||
:page="attachments.page"
|
||||
:size="attachments.size"
|
||||
:total="attachments.total"
|
||||
:size-options="[60, 120, 200]"
|
||||
@change="handlePaginationChange"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -428,6 +428,7 @@ function handleSelectUser(user: User | undefined) {
|
|||
:page="comments.page"
|
||||
:size="comments.size"
|
||||
:total="comments.total"
|
||||
:size-options="[20, 30, 50, 100]"
|
||||
@change="handlePaginationChange"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -638,6 +638,7 @@ function handleSortItemChange(sortItem?: SortItem) {
|
|||
:page="singlePages.page"
|
||||
:size="singlePages.size"
|
||||
:total="singlePages.total"
|
||||
:size-options="[20, 30, 50, 100]"
|
||||
@change="handlePaginationChange"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -928,6 +928,7 @@ function handleContributorChange(user?: User) {
|
|||
:page="posts.page"
|
||||
:size="posts.size"
|
||||
:total="posts.total"
|
||||
:size-options="[20, 30, 50, 100]"
|
||||
@change="handlePaginationChange"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -36,7 +36,7 @@ const grantPermissionModal = ref<boolean>(false);
|
|||
|
||||
const users = ref<UserList>({
|
||||
page: 1,
|
||||
size: 10,
|
||||
size: 20,
|
||||
total: 0,
|
||||
items: [],
|
||||
first: true,
|
||||
|
@ -486,6 +486,7 @@ onMounted(() => {
|
|||
:page="users.page"
|
||||
:size="users.size"
|
||||
:total="users.total"
|
||||
:size-options="[20, 30, 50, 100]"
|
||||
@change="handlePaginationChange"
|
||||
/>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue