對於複雜的應用程式,使用預先定義好的路徑來定義路由往往是不夠的。在 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"> <a>Go to pages/post/[pid].js</a> </Link> </li> <li> <Link href="/post/abc?foo=bar"> <a>Also goes to pages/post/[pid].js</a> </Link> </li> <li> <Link href="/post/abc/a-comment"> <a>Go to pages/post/[pid]/[comment].js</a> </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
。query
將會是一個空物件 ({}
)。經過水和 ( hydration )後,Next.js 將會觸發你的應用程式更新,來提供 query
物件裡的路由參數。
想知道更多下一步的資訊, 我們推薦以下的文章: