创建布局与页面

目前您的应用仅包含首页。接下来我们将学习如何通过布局 (layouts)页面 (pages) 创建更多路由。

嵌套路由

Next.js 采用基于文件系统的路由机制,其中文件夹用于创建嵌套路由。每个文件夹代表一个路由段 (route segment),对应 URL 中的一段路径。

展示文件夹如何映射到 URL 段的示意图

您可以使用 layout.tsxpage.tsx 文件为每个路由创建独立的用户界面。

page.tsx 是 Next.js 的特殊文件,用于导出 React 组件,这是路由可访问的必要条件。您的应用中已有一个页面文件:/app/page.tsx —— 这是与根路由 / 关联的首页。

要创建嵌套路由,您可以在文件夹内嵌套其他文件夹,并在其中添加 page.tsx 文件。例如:

展示如何通过添加 dashboard 文件夹创建新路由 '/dashboard' 的示意图

/app/dashboard/page.tsx 文件与 /dashboard 路径关联。让我们创建这个页面看看效果!

创建仪表盘页面

/app 目录下新建名为 dashboard 的文件夹。然后在该文件夹内创建 page.tsx 文件,内容如下:

/app/dashboard/page.tsx
export default function Page() {
  return <p>仪表盘页面</p>;
}

确保开发服务器正在运行,然后访问 http://localhost:3000/dashboard。您将看到"仪表盘页面"的文字。

这就是在 Next.js 中创建不同页面的方法:使用文件夹创建新路由段,并在其中添加 page 文件。

通过 page 文件的特殊命名规则,Next.js 允许您将 UI 组件、测试文件和其他相关代码与路由共置 (colocate)。只有 page 文件内的内容会被公开访问。例如,/ui/lib 文件夹就与您的路由一起共置于 /app 文件夹中。

练习:创建仪表盘页面

让我们练习创建更多路由。在仪表盘中创建两个新页面:

  1. 客户页面:可通过 http://localhost:3000/dashboard/customers 访问。目前只需返回 <p>客户页面</p> 元素。
  2. 发票页面:可通过 http://localhost:3000/dashboard/invoices 访问。目前也只需返回 <p>发票页面</p> 元素。

花些时间完成这个练习,完成后可查看下方折叠区域的解决方案:

创建仪表盘布局

仪表盘通常包含在多个页面间共享的导航组件。在 Next.js 中,您可以使用特殊的 layout.tsx 文件创建共享 UI。让我们为仪表盘页面创建布局!

/dashboard 文件夹内新建 layout.tsx 文件,粘贴以下代码:

/app/dashboard/layout.tsx
import SideNav from '@/app/ui/dashboard/sidenav';
 
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <div className="flex h-screen flex-col md:flex-row md:overflow-hidden">
      <div className="w-full flex-none md:w-64">
        <SideNav />
      </div>
      <div className="flex-grow p-6 md:overflow-y-auto md:p-12">{children}</div>
    </div>
  );
}

这段代码包含几个关键点,让我们逐一解析:

首先,您将 <SideNav /> 组件导入布局。任何导入此文件的组件都将成为布局的一部分。

<Layout /> 组件接收一个 children 属性。这个子元素可以是页面或其他布局。在您的案例中,/dashboard 内的页面会自动嵌套在 <Layout /> 中,如下所示:

展示仪表盘布局如何嵌套页面作为子元素的文件夹结构

保存更改并检查本地服务器,您应该看到以下效果:

包含侧边导航和主内容区的仪表盘页面

使用 Next.js 布局的一个优势是:在导航时,只有页面组件会更新,而布局不会重新渲染。这称为部分渲染 (partial rendering),它能在页面切换时保持布局中的客户端 React 状态。

展示导航时仅交换页面UI的仪表盘布局文件夹结构

根布局

在第 3 章中,您曾将 Inter 字体导入另一个布局:/app/layout.tsx。回顾一下:

/app/layout.tsx
import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={`${inter.className} antialiased`}>{children}</body>
    </html>
  );
}

这称为根布局 (root layout),是每个 Next.js 应用必需的。您添加到根布局的任何 UI 都会在所有页面间共享。您可以通过根布局修改 <html><body> 标签,并添加元数据(关于元数据的更多内容将在后续章节介绍)。

由于您刚创建的布局 (/app/dashboard/layout.tsx) 是仪表盘页面专用的,因此不需要在上面的根布局中添加任何 UI。

On this page