Logo
Published on

Next.js 入门到进阶:(三) 页面与路由

Authors
  • avatar
    Name
    xiaobai
    Twitter

在上一篇中,我们了解了 Next.js 的项目结构,其中 src/app 目录是 App Router 的核心。现在,我们来深入探索它的路由机制。

路由的基本概念

在 App Router 中,目录被用来定义路由。每个目录代表了 URL 的一个片段 (Segment)。而目录下的 page.tsx 文件则用来渲染该路由的 UI。

1. 创建新页面

让我们来创建一个“关于我们” (/about) 页面。

  1. src/app 目录下,创建一个名为 about 的新目录。
  2. src/app/about 目录下,创建一个 page.tsx 文件。

文件结构如下:

src/
└── app/
    ├── about/
    │   └── page.tsx  // `/about` 路由
    ├── layout.tsx
    └── page.tsx      // `/` 路由

现在,向 src/app/about/page.tsx 文件中添加以下代码:

// src/app/about/page.tsx

export default function AboutPage() {
  return (
    <main className="p-8">
      <h1 className="text-3xl font-bold">关于我们</h1>
      <p className="mt-4">这是一个使用 Next.js App Router 创建的页面。</p>
    </main>
  );
}

保存文件后,访问 http://localhost:3000/about,你就能看到刚刚创建的“关于我们”页面了。就这么简单!

2. 嵌套路由

你还可以通过创建嵌套目录来创建嵌套路由。例如,要创建一个 /dashboard/settings 页面:

  1. src/app 下创建 dashboard 目录。
  2. src/app/dashboard 下创建 settings 目录。
  3. src/app/dashboard/settings 下创建 page.tsx 文件。

文件结构:

src/
└── app/
    └── dashboard/
        └── settings/
            └── page.tsx // `/dashboard/settings` 路由

页面间的导航

要在页面之间进行跳转,我们使用 Next.js 提供的 <Link> 组件,而不是传统的 <a> 标签。

<Link> 组件有两大优势:

  1. 客户端导航: 它会在浏览器中通过 JavaScript 实现页面跳转,而不会重新加载整个页面,提供了类似单页应用 (SPA) 的流畅体验。
  2. 预取 (Prefetching): 当 <Link> 组件出现在视口中时,Next.js 会在后台自动预取链接页面的代码。这样,当用户点击链接时,页面几乎可以瞬时加载完成。

让我们在首页 (src/app/page.tsx) 添加一个指向“关于我们”页面的链接。

修改 src/app/page.tsx

import Link from 'next/link';

export default function HomePage() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-center p-24">
      <h1 className="text-4xl font-bold mb-8">欢迎来到我的 Next.js 应用</h1>
      <Link href="/about" className="text-blue-500 hover:underline">
        前往“关于我们”页面
      </Link>
    </main>
  );
}

现在回到首页 http://localhost:3000,点击链接,你会发现页面可以无刷新地快速跳转到 /about

动态路由 (Dynamic Routes)

通常,我们需要根据动态的参数来创建页面,例如博客文章的 ID、产品的 slug 等。在 App Router 中,这通过在目录名中使用方括号 [] 来实现。

创建动态路由

假设我们要创建一个博客系统,URL 结构为 /blog/[slug],其中 [slug] 是每篇文章的唯一标识。

  1. src/app 目录下创建 blog 目录。
  2. blog 目录下,创建一个名为 [slug] 的目录(没错,目录名就是 [slug])。
  3. src/app/blog/[slug] 目录下,创建一个 page.tsx 文件。

文件结构:

src/
└── app/
    └── blog/
        └── [slug]/
            └── page.tsx // `/blog/:slug` 路由

现在,编辑 src/app/blog/[slug]/page.tsx 文件,以获取并显示动态参数:

// src/app/blog/[slug]/page.tsx

type BlogPostParams = {
  params: {
    slug: string;
  };
};

export default function BlogPostPage({ params }: BlogPostParams) {
  return (
    <main className="p-8">
      <h1 className="text-3xl font-bold">博客文章</h1>
      <p className="mt-4">
        你正在查看的文章 slug 是: 
        <span className="font-mono bg-gray-200 p-1 rounded">{params.slug}</span>
      </p>
    </main>
  );
}

在这个组件中,params prop 会自动包含路由中的所有动态片段。因为我们的目录是 [slug],所以 params 对象中会有一个 slug 属性。

现在,你可以访问 http://localhost:3000/blog/hello-worldhttp://localhost:3000/blog/my-first-post,页面会正确地显示出 URL 中的 slug 部分。

总结

在这一章中,我们学习了 App Router 的核心功能:

  • 通过创建目录page.tsx 文件来定义路由。
  • 使用 <Link> 组件在页面间实现快速的客户端导航。
  • 通过使用方括号 [slug] 的目录结构来创建动态路由,并从 params prop 中获取动态参数。

掌握这些知识后,你就已经具备了构建多页面 Next.js 应用的基础。在下一篇中,我们将探讨如何为应用添加样式,包括全局样式、CSS Modules 和 Tailwind CSS。