176 lines
3.3 KiB
Vue
176 lines
3.3 KiB
Vue
<template>
|
|
<nav class="pagination">
|
|
<ul class="pages nolist">
|
|
<li>
|
|
<Link
|
|
:href="`/updates/${routeParams?.scope}/1`"
|
|
:class="{ disabled: !hasPrevPage }"
|
|
class="page first nolink"
|
|
><Icon icon="first2" /></Link>
|
|
</li>
|
|
|
|
<li>
|
|
<Link
|
|
:href="hasPrevPage ? `/updates/${routeParams?.scope}/${currentPage - 1}` : null"
|
|
:class="{ disabled: !hasPrevPage }"
|
|
class="page prev nolink"
|
|
><Icon icon="arrow-left" /></Link>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="index">
|
|
<ul class="pages before wrap nolist">
|
|
<li
|
|
v-for="page in prevPages"
|
|
:key="`page-${page}`"
|
|
>
|
|
<Link
|
|
:href="`/updates/${routeParams?.scope}/${page}`"
|
|
class="page nolink"
|
|
:class="{ active: page === currentPage }"
|
|
>{{ page }}</Link>
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="pages nolist">
|
|
<li>
|
|
<div class="page active">{{ currentPage }}</div>
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="pages after wrap nolist">
|
|
<li
|
|
v-for="page in nextPages"
|
|
:key="`page-${page}`"
|
|
>
|
|
<Link
|
|
:href="`/updates/${routeParams?.scope}/${page}`"
|
|
class="page nolink"
|
|
:class="{ active: page === currentPage }"
|
|
>{{ page }}</Link>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<ul class="pages nolist">
|
|
<li>
|
|
<Link
|
|
:href="hasNextPage ? `/updates/${routeParams?.scope}/${currentPage + 1}` : null"
|
|
:class="{ disabled: !hasNextPage }"
|
|
class="page next nolink"
|
|
><Icon icon="arrow-right" /></Link>
|
|
</li>
|
|
|
|
<li>
|
|
<Link
|
|
:href="`/updates/${routeParams?.scope}/${pageTotal}`"
|
|
:class="{ disabled: !hasNextPage }"
|
|
class="page last nolink"
|
|
><Icon icon="last2" /></Link>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { inject } from 'vue';
|
|
|
|
const { routeParams, pageProps } = inject('pageContext');
|
|
const currentPage = Number(routeParams?.page);
|
|
const limit = Number(pageProps.limit) || 30;
|
|
const total = Number(pageProps.total);
|
|
const pageTotal = Math.ceil(total / limit);
|
|
const hasNextPage = currentPage + 1 <= pageTotal;
|
|
const hasPrevPage = currentPage - 1 >= 1;
|
|
|
|
console.log(routeParams);
|
|
|
|
const prevPages = Array.from({ length: 4 }, (value, index) => {
|
|
const page = currentPage - index - 1;
|
|
|
|
if (page < 1) {
|
|
return null;
|
|
}
|
|
|
|
return page;
|
|
}).filter(Boolean);
|
|
|
|
const nextPages = Array.from({ length: 4 }, (value, index) => {
|
|
const page = currentPage + index + 1;
|
|
|
|
if (page > pageTotal) {
|
|
return null;
|
|
}
|
|
|
|
return page;
|
|
}).filter(Boolean);
|
|
|
|
console.log(total, limit, currentPage);
|
|
console.log(prevPages);
|
|
console.log(nextPages);
|
|
</script>
|
|
|
|
<style scoped>
|
|
.pagination {
|
|
height: 5rem;
|
|
display: flex;
|
|
justify-content: center;
|
|
padding: 1rem;
|
|
font-size: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.pages {
|
|
display: flex;
|
|
}
|
|
|
|
.wrap {
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.before {
|
|
flex-direction: row-reverse;
|
|
}
|
|
|
|
.index {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.page {
|
|
width: 3rem;
|
|
height: 3rem;
|
|
display: inline-flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin-bottom: 1rem;
|
|
background: var(--background);
|
|
box-shadow: 0 0 3px var(--shadow-weak-30);
|
|
color: var(--shadow);
|
|
font-weight: bold;
|
|
font-size: 1rem;
|
|
|
|
.icon {
|
|
width: .9rem;
|
|
height: .9rem;
|
|
fill: var(--shadow);
|
|
}
|
|
|
|
&.active {
|
|
color: var(--primary);
|
|
}
|
|
|
|
&.disabled .icon {
|
|
fill: var(--shadow-weak-20);
|
|
}
|
|
}
|
|
|
|
.prev {
|
|
margin-right: .5rem;
|
|
}
|
|
|
|
.next {
|
|
margin-left: .5rem;
|
|
}
|
|
</style>
|