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