動態路由

例子

對於複雜的應用程式,使用預先定義好的路徑來定義路由往往是不夠的。在 Next.js 中,你可以將中括號添加到頁面 ([param])來創建一個動態路由(又稱為網址別名( url slugs )、漂亮的路由( pretty urls )等)。

思考一下這個頁面 pages/post/[pid].js :

import { useRouter } from 'next/router' const Post = () => { const router = useRouter() const { pid } = router.query return <p>Post: {pid}</p> } export default Post

/post/1/post/abc 等的路由都會被 pages/post/[pid].js 匹配。匹配的路徑參數將會被當成一個查詢參數( query params )發送至頁面,並且與其他查詢參數合併。

舉例來說,路由 /post/abc 將具有以下的 query 物件。

{ "pid": "abc" }

同樣地,路由 /post/abc?foo=bar 將具有以下的 query 物件。

{ "foo": "bar", "pid": "abc" }

然而,路由參數將會覆蓋同樣名稱的查詢參數。舉例來說, /post/abc?pid=123 將具有以下的 query 物件。

{ "pid": "abc" }

多重動態路由片段也是依照相同方法來運作。頁面 pages/post/[pid]/[comment].js 將會匹配路由 /post/abc/a-comment , 並且它的 query 物件將會是:

{ "pid": "abc", "comment": "a-comment" }

客戶端導航到動態路由用 next/link 處理。如果我們想要連結到上面使用的路由,它看起來像是:

import Link from 'next/link' function Home() { return ( <ul> <li> <Link href="/post/abc"> Go to pages/post/[pid].js </Link> </li> <li> <Link href="/post/abc?foo=bar"> Also goes to pages/post/[pid].js </Link> </li> <li> <Link href="/post/abc/a-comment"> Go to pages/post/[pid]/[comment].js </Link> </li> </ul> ) } export default Home

閱讀我們的文件 Linking between pages 來學習更多。

捕獲所有的路由

例子

可以通過在括號內加入三個點 (...) 來擴展動態路由以捕獲所有路徑。例如:

  • pages/post/[...slug].js 能匹配 /post/a ,也能匹配 /post/a/b/post/a/b/c 等。

注意: 你可以使用 slug 以外的名稱, 例如: [...param]

匹配的參數將作為查詢參數( 範例中是 slug )發送到頁面,並且它始終都會是一個陣列,因此,路徑 /post/a 將具有以下的 query 物件。

{ "slug": ["a"] }

/post/a/b 和任何其他路徑匹配的情況下,新的參數將會被添加到陣列中,如下所示:

{ "slug": ["a", "b"] }

可選的捕獲所有路由

通過將參數包在雙括號([[...slug]])中,可以使捕獲所有路由變成是可選的。

舉例來說, pages/post/[[...slug]].js 將匹配 /post/post/a/post/a/b 等。

捕獲所有路由和可選捕獲所有路由最大的差別在於,當使用可選捕獲時,沒有帶參數的路由也被匹配到 ( 上面例子中的 /post)。

query 物件如下:

{ } // GET `/post` (empty object) { "slug": ["a"] } // `GET /post/a` (single-element array) { "slug": ["a", "b"] } // `GET /post/a/b` (multi-element array)

注意事項

  • 預先定義路由的優先順序高於動態路由,動態路由的優先度高於捕獲所有路由,請看以下的範例:
  • pages/post/create.js - 將會匹配 /post/create
  • pages/post/[pid].js - 將會匹配 /post/1/post/abc 等。但不會匹配 /post/create
  • pages/post/[...slug].js - 將會匹配 /post/1/2/post/a/b/c 等。但不會匹配 /post/create, /post/abc
  • 通過 自動靜態最佳化 進行靜態最佳化的頁面將會在沒有提供路由參數的情況下水合( hydrated ),換句話說 query 將會是一個空物件 ({})。

經過水和 ( hydration )後,Next.js 將會觸發你的應用程式更新,來提供 query 物件裡的路由參數。

相關文件

想知道更多下一步的資訊, 我們推薦以下的文章:

本篇文章由DoubleLazyZ

DoubleLazyZ

貢獻翻譯。瞭解如何參與貢獻