You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Astro.js内置分页如何传递动态过滤变量?是否需自定义分页

Astro.js 动态过滤+分页问题解决方案

核心结论

Astro 内置的 getStaticPaths 分页是构建阶段静态生成的,无法直接支持动态变化的 filterValue。如果要实现带动态过滤的分页,要么切换到 SSR 模式,要么自行实现前端/服务端的动态分页逻辑。


1. 为什么 filterValue 无法在 getStaticPaths 中使用?

getStaticPaths 是 Astro 在项目构建时执行的函数,它的运行上下文和页面的客户端/运行时上下文完全隔离:

  • 外部声明的动态变量(比如用户输入的过滤条件)属于运行时数据,构建阶段根本无法获取
  • 静态路径一旦生成,部署后就固定不变,刷新页面也不会重新执行 getStaticPaths,这就是你刷新后分页无法重建的原因

2. 可行解决方案

方案一:切换到 Astro SSR 模式(推荐,适合大数据量)

如果你的项目可以部署到支持 Node.js 的平台(比如 Vercel、Netlify Functions),可以放弃静态分页,改用服务器端动态处理:

  • 通过 Astro.url.searchParams 获取 URL 上的过滤参数(如 ?filter=xxx&page=1)
  • 每次请求时,带着过滤参数和分页参数去 Directus 拉取对应数据
  • 自行计算分页信息(总页数、当前页等)并渲染分页控件

示例代码:

---
import { fetchItems } from '../utils/directus';

// 从URL获取过滤条件和当前页
const currentPage = Number(Astro.url.searchParams.get('page')) || 1;
const filterValue = Astro.url.searchParams.get('filter') || '';
const pageSize = 9;

// 调用Directus SDK,传入过滤和分页参数
const { data: items, meta } = await fetchItems(filterValue, {
  limit: pageSize,
  offset: (currentPage - 1) * pageSize,
});
const totalPages = Math.ceil(meta.total / pageSize);
---

<!-- 渲染内容列表 -->
<div class="items-grid">
  {items.map(item => (
    <div class="item-card">
      <h3>{item.title}</h3>
      <p>{item.description}</p>
    </div>
  ))}
</div>

<!-- 渲染分页控件 -->
<div class="pagination">
  {currentPage > 1 && (
    <a href={`?filter=${filterValue}&page=${currentPage - 1}`}>上一页</a>
  )}
  {Array.from({ length: totalPages }, (_, i) => i + 1).map(pageNum => (
    <a 
      href={`?filter=${filterValue}&page=${pageNum}`}
      class={pageNum === currentPage ? 'active' : ''}
    >
      {pageNum}
    </a>
  ))}
  {currentPage < totalPages && (
    <a href={`?filter=${filterValue}&page=${currentPage + 1}`}>下一页</a>
  )}
</div>

方案二:前端动态过滤+本地分页(适合小数据量)

如果你的数据总量不大,可以一次性拉取全部数据到前端,用 JavaScript 实现实时过滤和分页:

  • 构建时或客户端初始化时拉取全量数据
  • 监听过滤输入框的变化,实时过滤数据
  • 用前端状态维护当前页,渲染对应页的内容

示例思路:

---
import { fetchItems } from '../utils/directus';

// 构建时拉取全量数据(或客户端用fetch拉取)
const allItems = await fetchItems('');
---

<script>
  // 初始化数据
  const rawItems = JSON.parse('{JSON.stringify(allItems)}');
  let filteredItems = [...rawItems];
  let currentPage = 1;
  const pageSize = 9;

  // 渲染当前页内容
  function renderCurrentPage() {
    const startIdx = (currentPage - 1) * pageSize;
    const pageItems = filteredItems.slice(startIdx, startIdx + pageSize);
    const container = document.getElementById('items-container');
    container.innerHTML = pageItems.map(item => `
      <div class="item-card">
        <h3>${item.title}</h3>
        <p>${item.description}</p>
      </div>
    `).join('');
    renderPagination();
  }

  // 渲染分页控件
  function renderPagination() {
    const totalPages = Math.ceil(filteredItems.length / pageSize);
    const container = document.getElementById('pagination-container');
    container.innerHTML = `
      ${currentPage > 1 ? `<button onclick="changePage(${currentPage - 1})">上一页</button>` : ''}
      ${Array.from({ length: totalPages }, (_, i) => i + 1).map(num => 
        `<button onclick="changePage(${num})" ${num === currentPage ? 'class="active"' : ''}>${num}</button>`
      ).join('')}
      ${currentPage < totalPages ? `<button onclick="changePage(${currentPage + 1})">下一页</button>` : ''}
    `;
  }

  // 切换页码
  function changePage(pageNum) {
    currentPage = pageNum;
    renderCurrentPage();
  }

  // 处理过滤输入
  document.getElementById('filter-input').addEventListener('input', (e) => {
    const keyword = e.target.value.trim().toLowerCase();
    filteredItems = rawItems.filter(item => 
      item.title.toLowerCase().includes(keyword) || 
      item.description.toLowerCase().includes(keyword)
    );
    currentPage = 1; // 过滤后回到第一页
    renderCurrentPage();
  });

  // 初始化渲染
  renderCurrentPage();
</script>

<input id="filter-input" type="text" placeholder="输入关键词过滤">
<div id="items-container"></div>
<div id="pagination-container"></div>

3. 内置分页的适用场景

Astro 的 paginate 只适合静态、无动态过滤需求的场景,比如固定分类的博客列表、归档页面等——这些内容在构建时就确定,不需要根据用户输入变化。

内容的提问来源于stack exchange,提问作者Biacho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:22:08