Frontend Lab
← 回到所有模式
PA07🧩 Compose · 互動組合分頁

Pagination

分頁器

難度 ★★★★★標籤 分頁 · 省略 · 邊界3 min read

模式簡述

分頁看似簡單,邊界狀態超多:第一頁、最後一頁、只有一頁、零筆。 省略邏輯(1 … 4 5 6 … 20)才是分頁器的精華。

1 頁 / 共 10

第 1 頁|首頁 — 上一頁 disabled

Claude Code Prompt

💬 Claude Code Prompt
參考:PA07 pagination
技術:純 React,邊界邏輯

具體行為:
- 顯示:< 1 ... 4 5 6 ... 20 >(current 高亮)
- 第 1 頁:< disabled
- 最後一頁:> disabled
- < 7 頁:全部顯示,沒有省略
- 只有 1 頁:整個分頁器隱藏
- 0 筆:顯示「沒有資料」訊息,不顯示分頁

省略邏輯:
- pages = [1]
- 如果 current > 3,加 '…'
- 加 [current-1, current, current+1] 範圍(夾在 2 到 total-1)
- 如果 current < total-2,加 '…'
- pages.push(total)

限制:
- disabled 用 opacity-40 + cursor-not-allowed,不要 hidden
- current 用 lab-accent 高亮,其他都 muted
- 千萬不要顯示「1 2 3 ... 99 100」這種一字排開(手機會炸)

完整程式碼

Pagination.tsx
function buildPages(current: number, total: number): (number | '…')[] {
if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1)
const pages: (number | '…')[] = [1]
if (current > 3) pages.push('…')
for (let i = Math.max(2, current - 1); i <= Math.min(total - 1, current + 1); i++) {
  pages.push(i)
}
if (current < total - 2) pages.push('…')
pages.push(total)
return pages
}

export function Pagination({ current, total, onChange }) {
if (total === 0) return <p>沒有資料</p>
if (total === 1) return null
const pages = buildPages(current, total)

return (
  <nav>
    <button disabled={current === 1} onClick={() => onChange(current - 1)}></button>
    {pages.map((p, i) =>
      p === '…'
        ? <span key={i}></span>
        : <button key={p} className={p === current ? 'active' : ''} onClick={() => onChange(p)}>{p}</button>
    )}
    <button disabled={current === total} onClick={() => onChange(current + 1)}></button>
  </nav>
)
}

何時用

  • ✅ 文章列表、產品列表
  • ✅ 後台資料表格(搭配 page size 選項)
  • ✅ 搜尋結果頁

何時別用

  • ❌ 動態瀑布流 / 社群動態(用 infinite scroll)
  • ❌ 資料 < 一頁(隱藏分頁,不要顯示「1/1」)
  • ❌ 需要快速跳到特定資料(用搜尋更直接)

我踩過的坑

  1. 沒處理只有一頁:顯示「1/1」+ 灰色 ‹ › 兩端,看起來像 bug。 只有一頁直接 return null。

  2. 省略邏輯沒夾邊界:current 1 的時候顯示「1 0 -1 ... 20」,超尷尬。 要用 Math.max(2, current - 1)Math.min(total - 1, current + 1) 夾住。

  3. disabled 用 hidden:第一頁時 ‹ 消失,按鈕位置會跳。 用 opacity-40 + cursor-not-allowed 保留空間。

相關模式

  • 暫無

搜尋

按 ⌘K 隨時開啟