Astro实现分页
为需要分页的page创建对应文件
例如创建archives/[…page].astro
使用paginate函数返回一个page。
export async function getStaticPaths({ paginate }: { paginate: Function }) {
const posts = await getCollection("blog");
posts.sort((a, b) => {
return b.data.pubDate.getTime() - a.data.pubDate.getTime();
});
return paginate(posts, {
pageSize: config.paginate,
});
}
type Props = {
page: {
data: CollectionEntry<"blog">[];
url: {
prev: string;
next: string;
};
currentPage: number;
lastPage: number;
total: number;
};
};
const { page } = Astro.props;
根据当前页和总页数计算分页按钮
从 page中渲染对应的分页按钮,创建一个对应的分页器函数,返回page number list。
我指定了中心渲染最大的页码:maxLinks
const renderPaginator = (
totalPages: number,
currentPage: number,
href: string,
maxLinks: number
) => {
const paginationLinks: any[] = [];
// 计算分页器的起始页码和结束页码
let startPage: number, endPage: number;
if (totalPages <= maxLinks) {
startPage = 1;
endPage = totalPages;
} else {
let halfmaxLinks = Math.floor(maxLinks / 2);
startPage = Math.max(1, currentPage - halfmaxLinks);
endPage = Math.min(totalPages, currentPage + halfmaxLinks);
if (endPage - startPage < maxLinks - 1) {
if (currentPage <= halfmaxLinks) {
endPage = Math.min(maxLinks, totalPages);
} else if (currentPage >= totalPages - halfmaxLinks) {
startPage = Math.max(totalPages - maxLinks + 1, 1);
}
}
}
// 如果起始页码大于1,添加"1..."按钮
if (startPage > 1) {
paginationLinks.push({ page: 1, isActive: false, href });
if (startPage > 2) {
paginationLinks.push({ page: "···", isActive: false, href: "#" });
}
}
// 添加页码按钮
for (let page = startPage; page <= endPage; page++) {
paginationLinks.push({
page,
isActive: page === currentPage,
href: page > 1 ? `${href}/${page}` : `${href}`,
});
}
// 如果结束页码小于总页数,添加"...n"按钮
if (endPage < totalPages) {
if (endPage < totalPages - 1) {
paginationLinks.push({ page: "···", isActive: false, href: "#" });
}
paginationLinks.push({
page: totalPages,
isActive: false,
href: `${href}/${totalPages}`,
});
}
return paginationLinks;
};
const paginationLinks = renderPaginator(last, current, url, paginate_max_links);
然后从这个数组渲染对应的page number
渲染分页
<ul class="flex flex-row flex-auto justify-around items-center space-x-3">
{
previous && (
<PaginationLink href={previous} title="上一页">
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-5 h-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
</PaginationLink>
)
}
{
last > 1 &&
paginationLinks.map(({ page, isActive, href }) => (
<PaginationLink href={href} isActive={isActive} title={page}>
{page}
</PaginationLink>
))
}
{
next && (
<PaginationLink href={next} title="下一页">
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-5 h-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
/>
</svg>
</PaginationLink>
)
}
</ul>
可以参考我这个归档页面的分页。