Skip to content

Layout 布局

基本布局

  1. 根布局是必须的,即使删除 app/layout.tsx 文件,Next.js 也会自动创建一个默认的根布局。
  2. 布局组件可以接收 children 属性,表示该布局下的子页面内容。

示例:

bash
next-app/
├── app/
   ├── layout.tsx # 根布局(强制性的)
   ├── page.tsx
   ├── global.css

每一个 page.tsx 通过 children 属性将子组件传递给布局组件。

tsx
export const metadata = {
  title: 'Next.js',
  description: 'Generated by Next.js',
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

嵌套布局

嵌套布局允许在不同的路由下使用不同的布局。每个嵌套路由可以有自己的布局文件。

示例:

bash
next-app/
├── app/
   ├── layout.tsx       # 根布局
   ├── page.tsx
   ├── global.css
   └── dashboard/
       ├── layout.tsx   # 子布局
       └── page.tsx

dashboard/layout.tsx 中,可以定义特定于该路由的布局:

tsx
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
  return (
    <div>
      <header>Dashboard Header</header>
      <main>{children}</main>
      <footer>Dashboard Footer</footer>
    </div>
  )
}

路由组布局

为路由组定义特定的布局。

bash
next-app/
├── app/
   ├── layout.tsx      # 根布局
   ├── page.tsx
   ├── global.css
   └── (auth)/
       ├── layout.tsx  # 路由组布局
       ├── login/
   └── page.tsx
       └── register/
           └── page.tsx
tsx
export default function AuthLayout({ children }: { children: React.ReactNode }) {
  return (
    <div>
      <header>Auth Header</header>
      <main>{children}</main>
      <footer>Auth Footer</footer>
    </div>
  )
}

Layout 中处理错误

目录结构:

bash
next-app/
├── app/
   ├── layout.tsx
   ├── template.tsx
   ├── error.tsx
   ├── loading.tsx
   ├── not-found.tsx
   └── page.tsx

示例:

tsx
<Layout>
  <Template>
    <ErrorBoundary fallback={<Error />}>
      <Suspense fallback={<Loading />}>
        <ErrorBoundary fallback={<NotFound />}>
          <Page />
        </ErrorBoundary>
      </Suspense>
    </ErrorBoundary>
  </Template>
</Layout>

基于 MIT 许可发布