路由

Next.js 以 頁面的概念 打造出基於檔案系統( file-system )的路由功能。

當一個檔案被加進 pages 資料夾,它會自動地變成可用的路由。

這些被加入 pages 資料夾的檔案被用來定義最常見的模式。

索引路由

路由器會自動地將命名為 index 的檔案作為資料夾根目錄的頁面。

  • pages/index.js/
  • pages/blog/index.js/blog

巢狀路由

路由器支援巢狀檔案。如果你建立了一個巢狀的資料夾結構,檔案仍然會依照相同的方式自動地配置路由。

  • pages/blog/first-post.js/blog/first-post
  • pages/dashboard/settings/username.js/dashboard/settings/username

動態路由片段

如果要匹配一個動態路由片段,你可以使用中括號。這可以使其與參數名稱相匹配。

  • pages/blog/[slug].js/blog/:slug (/blog/hello-world)
  • pages/[username]/settings.js/:username/settings (/foo/settings)
  • pages/post/[...all].js/post/* (/post/2020/id/title)

查看 Dynamic Routes documentation 頁面可以學習更多動態路由如何運作。

連結頁面

Next.js 的路由允許你使用客戶端路由來跳轉頁面,相似於單頁式應用程式( single-page application )。

一個稱作 Link 的 React 元件可以供你用來作為客戶端的路由跳轉。

import Link from 'next/link' function Home() { return ( <ul> <li> <Link href="/"> Home </Link> </li> <li> <Link href="/about"> About Us </Link> </li> <li> <Link href="/blog/hello-world"> Blog Post </Link> </li> </ul> ) } export default Home

上面的例子用了多個連結,每個連結都對應著一個已知頁面的路徑(href):

  • /pages/index.js
  • /aboutpages/about.js
  • /blog/hello-worldpages/blog/[slug].js

任何出現在畫面中的 <Link /> 元件(包含頁面初始化或後續使用者向下捲動頁面)如果指向使用了 靜態生成 ,將會被提前載入(包含該頁面所需的資料)。使用 伺服器端渲染 的頁面 不會 提前載入。

連結動態路徑

你也可以使用插入變數的方式來建立一個路徑,這時 動態路由片段 可以派得上用場。舉例來說,顯示一個已經被當成 props 傳入元件的文章清單。

import Link from 'next/link' function Posts({ posts }) { return ( <ul> {posts.map((post) => ( <li key={post.id}> <Link href={`/blog/${encodeURIComponent(post.slug)}`}> {post.title} </Link> </li> ))} </ul> ) } export default Posts

在以下範例中使用了 encodeURIComponent 來確保路徑可以兼容 utf-8 編碼格式。

或者,使用 URL 物件( URL Object ):

import Link from 'next/link' function Posts({ posts }) { return ( <ul> {posts.map((post) => ( <li key={post.id}> <Link href={{ pathname: '/blog/[slug]', query: { slug: post.slug }, }} > {post.title} </Link> </li> ))} </ul> ) } export default Posts

現在我們使用 URL 物件來建立路徑,而不是使用插入變數的方式:

  • pathnamepages 資料夾裡的頁面名稱。如同 /blog/[slug] 這個例子一樣。
  • query 是一個有著動態片段的物件。如同 slug 這個例子一樣。

注入路由

範例

在 React 的元件中,你可以使用 useRouter 或者 withRouter 來存取 router 物件

一般來說,我們建議使用 useRouter

學習更多

路由器被分成許多的部分:

本篇文章由DoubleLazyZ

DoubleLazyZ

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