javascriptnext.jsreact.js

Next.js 中的路由类型详解

ext.js 自 13 版本引入了 App Router,为路由系统带来了更强大的功能。虽然 Pages Router 依然保留,适合逐步迁移,但 App Router 已成为主流推荐方式。本文将基于 App Router 的新特性,同时补充 Pages Router,帮助您深入

2024-11-18·阅读约 9 分钟·计算中...

Next.js 自 13 版本引入了 App Router,为路由系统带来了更强大的功能。虽然 Pages Router 依然保留,适合逐步迁移,但 App Router 已成为主流推荐方式。本文将基于 App Router 的新特性,同时补充 Pages Router,帮助您深入了解 Next.js 的路由类型和使用场景。


1. App Router 路由概述

App Router 位于 app/ 目录,通过文件系统定义路由,支持动态路由、嵌套路由、路由分组和更灵活的布局管理。相比 Pages Router,它更适合构建复杂的模块化应用。

目录结构映射

app/ 文件结构对应最终 URL:

app/
  page.js       ➡ `/`
  about/
    page.js     ➡ `/about`
  blog/
    [id]/
      page.js   ➡ `/blog/:id`

基本规则

  • 文件名为 page.js 定义页面组件。
  • 文件夹嵌套决定路径层级。
  • 动态参数使用 [param],支持更复杂的 URL 处理。

2. App Router 的路由类型

2.1 静态路由

通过创建 page.js 文件定义固定路径。

示例

app/
  about/
    page.js     ➡ `/about`

代码:app/about/page.js

export default function About() {
  return <h1>About Us</h1>;
}

访问 /about 时,将显示:

About Us

2.2 动态路由

动态参数用 [param] 表示,支持捕获 URL 的动态部分。

示例

app/
  blog/
    [id]/
      page.js   ➡ `/blog/:id`

代码:app/blog/[id]/page.js

export default function BlogPost({ params }) {
  const { id } = params;
  return <h1>Blog Post ID: {id}</h1>;
}

访问 /blog/42 时,将显示:

Blog Post ID: 42

2.3 嵌套路由

通过嵌套文件夹实现模块化路径,支持多级页面和分层布局。

示例

app/
  dashboard/
    page.js         ➡ `/dashboard`
    analytics/
      page.js       ➡ `/dashboard/analytics`
    reports/
      [year]/
        page.js     ➡ `/dashboard/reports/:year`

访问 /dashboard/reports/2023 时,将显示:

Reports for Year: 2023

2.4 Catch-All 路由

[...param] 捕获路径中所有剩余部分。

示例

app/
  docs/
    [...slug]/
      page.js   ➡ `/docs/*`

代码:app/docs/[...slug]/page.js

export default function Docs({ params }) {
  const { slug } = params;
  return <h1>Docs Path: {slug.join('/')}</h1>;
}

访问 /docs/guides/advanced 时,将显示:

Docs Path: guides/advanced

2.5 可选 Catch-All 路由

[[...param]] 表示动态参数为可选。

示例

app/
  docs/
    [[...slug]]/
      page.js   ➡ `/docs` 或 `/docs/*`

代码:app/docs/[[...slug]]/page.js

export default function Docs({ params }) {
  const { slug } = params || [];
  return <h1>Docs Path: {slug.length ? slug.join('/') : 'Home'}</h1>;
}

访问 /docs 时显示:

Docs Path: Home

访问 /docs/setup 时显示:

Docs Path: setup

2.6 路由分组

() 包裹文件夹实现逻辑分组,不影响实际 URL。

示例

app/
  (marketing)/
    blog/
      page.js   ➡ `/blog`
  dashboard/
    page.js     ➡ `/dashboard`

分组 (marketing) 只影响代码逻辑结构,/blog 仍为实际路径。


2.7 API 路由

通过 app/api 创建 API 接口。

示例

app/
  api/
    hello/
      route.js   ➡ `/api/hello`

代码:app/api/hello/route.js

export async function GET() {
  return new Response(JSON.stringify({ message: 'Hello, API!' }), {
    headers: { 'Content-Type': 'application/json' },
  });
}

访问 /api/hello 时返回:

{ "message": "Hello, API!" }

3. Pages Router 支持

虽然 App Router 是主推方式,但 Pages Router 依然适用于简单项目或渐进迁移。

Pages Router 路由类型

路由类型 示例路径 定义方式
静态路由 /about pages/about.js
动态路由 /blog/:id pages/blog/[id].js
Catch-All 路由 /docs/* pages/docs/[...slug].js
API 路由 /api/hello pages/api/hello.js

渐进迁移

  • 将简单页面保留在 pages/
  • 将复杂路由迁移至 app/

4. App Router 的优势

功能 App Router Pages Router
动态布局 ✅ 支持 ❌ 不支持
路由分组 ✅ 支持 ❌ 不支持
数据获取(Streaming) ✅ 原生支持 ❌ 需手动配置
多级嵌套路由 ✅ 更加灵活 ✅ 支持但较繁琐

5. 总结与推荐

  1. App Router 是未来:推荐将新项目优先构建在 app/ 目录下。
  2. 渐进迁移:如果已有 pages/ 项目,可以逐步迁移到 App Router。
  3. 高效路由管理:充分利用动态路由、Catch-All 路由和路由分组,打造模块化应用。

通过掌握 App Router 的特性,您可以更高效地构建复杂的现代 Web 应用!

订阅 FreeMac

每周精选:Mac 高效技巧、免费替代付费软件、开发者工具推荐。用对你的 MacBook,省钱 + 提效。