Next.js 布局和頁(yè)面創(chuàng)建:新手指南

2025-03-20 10:29 更新

如何創(chuàng)建布局和頁(yè)面

Next.js 使用基于文件系統(tǒng)的路由,這意味著你可以通過(guò)文件夾和文件來(lái)定義路由。本頁(yè)將指導(dǎo)你如何創(chuàng)建布局和頁(yè)面,以及如何在它們之間鏈接。

創(chuàng)建頁(yè)面

頁(yè)面是在特定路由上渲染的 UI。要?jiǎng)?chuàng)建一個(gè)頁(yè)面,只需在 app 目錄中添加一個(gè) page 文件,并默認(rèn)導(dǎo)出一個(gè) React 組件。例如,要?jiǎng)?chuàng)建一個(gè)索引頁(yè)面(/):

Next.js教程創(chuàng)建頁(yè)面

  1. export default function Page() {
  2. return <h1>Hello W3Cschool!</h1>
  3. }

創(chuàng)建布局

布局是在多個(gè)頁(yè)面之間共享的 UI。在導(dǎo)航時(shí),布局會(huì)保留狀態(tài)、保持交互性,并且不會(huì)重新渲染。

你可以通過(guò)從 layout 文件中默認(rèn)導(dǎo)出一個(gè) React 組件來(lái)定義布局。該組件應(yīng)接受一個(gè) children 屬性,該屬性可以是一個(gè)頁(yè)面或另一個(gè)布局。

例如,要?jiǎng)?chuàng)建一個(gè)接受索引頁(yè)面作為子元素的布局,在 app 目錄中添加一個(gè) layout 文件:

Next.js教程創(chuàng)建布局

  1. export default function DashboardLayout({
  2. children,
  3. }: {
  4. children: React.ReactNode
  5. }) {
  6. return (
  7. <html lang="zh">
  8. <body>
  9. {/* 布局 UI */}
  10. {/* 在此處渲染頁(yè)面或嵌套布局 */}
  11. <main>{children}</main>
  12. </body>
  13. </html>
  14. )
  15. }

上述布局被稱為根布局,因?yàn)樗?app 目錄的根部定義。根布局是必需的,并且必須包含 htmlbody 標(biāo)簽。

創(chuàng)建嵌套路由

嵌套路由是由多個(gè) URL 段組成的路由。例如,/blog/[slug] 路由由三個(gè)段組成:

  • /(根段)
  • blog(段)
  • [slug](葉段)

在 Next.js 中:

  • 文件夾用于定義映射到 URL 段的路由段。
  • 文件(如 pagelayout)用于創(chuàng)建在段中顯示的 UI。

要?jiǎng)?chuàng)建嵌套路由,你可以將文件夾彼此嵌套。例如,要添加一個(gè) /blog 路由,在 app 目錄中創(chuàng)建一個(gè)名為 blog 的文件夾。然后,要使 /blog 公開訪問(wèn),添加一個(gè) page 文件:

Next.js中文教程-創(chuàng)建嵌套路由

  1. import { getPosts } from '@/lib/posts'
  2. import { Post } from '@/ui/post'
  3. export default async function Page() {
  4. const posts = await getPosts()
  5. return (
  6. <ul>
  7. {posts.map((post) => (
  8. <Post key={post.id} post={post} />
  9. ))}
  10. </ul>
  11. )
  12. }

你可以繼續(xù)嵌套文件夾來(lái)創(chuàng)建嵌套路由。例如,要為特定博客文章創(chuàng)建一個(gè)路由,在 blog 文件夾中創(chuàng)建一個(gè)新 [slug] 文件夾,并添加一個(gè) page 文件:

Next.js中文教程-繼續(xù)嵌套文件夾來(lái)創(chuàng)建嵌套路由

  1. function generateStaticParams() {}
  2. export default function Page() {
  3. return <h1>Hello, Blog Post Page!</h1>
  4. }

小貼士:將文件夾名稱用方括號(hào)括起來(lái)(例如 [slug])會(huì)創(chuàng)建一個(gè)特殊的動(dòng)態(tài)路由段,用于從數(shù)據(jù)生成多個(gè)頁(yè)面。這對(duì)于博客文章、產(chǎn)品頁(yè)面等非常有用。

嵌套布局

默認(rèn)情況下,文件夾層次結(jié)構(gòu)中的布局也會(huì)被嵌套,這意味著它們通過(guò) children 屬性包裹子布局。你可以在特定路由段(文件夾)中添加 layout 來(lái)嵌套布局。

例如,要為 /blog 路由創(chuàng)建一個(gè)布局,在 blog 文件夾中添加一個(gè)新 layout 文件。

Next.js中文教程-嵌套布局

  1. export default function BlogLayout({
  2. children,
  3. }: {
  4. children: React.ReactNode
  5. }) {
  6. return <section>{children}</section>
  7. }

如果你將上述兩個(gè)布局結(jié)合起來(lái),根布局(app/layout.js)將包裹博客布局(app/blog/layout.js),而博客布局又將包裹博客頁(yè)面(app/blog/page.js)和博客文章頁(yè)面(app/blog/[slug]/page.js)。

頁(yè)面之間的鏈接

你可以使用 <Link> 組件在路由之間導(dǎo)航。<Link> 是 Next.js 的內(nèi)置組件,它擴(kuò)展了 HTML 的 <a> 標(biāo)簽,提供了預(yù)取和客戶端導(dǎo)航功能。

例如,要生成博客文章列表,從 next/link 導(dǎo)入 <Link>,并為組件傳遞一個(gè) href 屬性:

  1. import Link from 'next/link'
  2. export default async function Post({ post }) {
  3. const posts = await getPosts()
  4. return (
  5. <ul>
  6. {posts.map((post) => (
  7. <li key={post.slug}>
  8. <Link href={`/blog/${post.slug}`}>{post.title}</Link>
  9. </li>
  10. ))}
  11. </ul>
  12. )
  13. }

<Link> 是在 Next.js 應(yīng)用程序中路由之間導(dǎo)航的主要和推薦方式。不過(guò),對(duì)于更高級(jí)的導(dǎo)航,你也可以使用 useRouter 鉤子。

API 參考

閱讀 API 參考 ,了解有關(guān)本頁(yè)中提到的功能的更多信息。

  • layout.js
    layout.js 文件的 API 參考。

  • page.js
    page.js 文件的 API 參考。

  • 鏈接
    使用內(nèi)置的 'next/link' 組件實(shí)現(xiàn)快速的客戶端導(dǎo)航。
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)