Next.js路由全解析:Pages Router 与 App Router,你选对了吗?

大家好,我是大鱼,一名热爱前端的普通开发者。

今天我们来深入探讨Next.js中两个重要的路由系统:Pages Router和App Router。

什么是Next.js路由?

在开始深入比较之前,让我们先简单回顾一下Next.js的路由系统。Next.js使用基于文件系统的路由,这意味着你文件目录的结构决定了你应用程序的路由结构。

多年来,Next.js开发者习惯将页面放置在"pages"目录中,这就是我们所说的Pages Router

后来,Next.js推出了新的App Router,显著改变了我们创建页面的方式。

Pages Router:经典而成熟的选择

基本结构

在Pages Router中,你的项目结构通常是这样:

markdown 复制代码
└── pages
    ├── about.js
    ├── index.js
    └── team.js

每个JavaScript/TypeScript文件对应一个路由,例如pages/about.js对应/about路由。

特点与使用方式

Pages Router采用"客户端优先"的思维模式,通过getServerSideProps等函数"拉取"服务端能力。数据获取主要在页面级别,集中在getStaticProps/getServerSideProps中。

在Pages Router中,你可以使用useRouterHook来实现页面跳转:

jsx 复制代码
import { useRouter } from 'next/router';

function MyComponent() {
  const router = useRouter();
  
  const handleClick = () => {
    router.push('/about');
  };
  
  return (
    <button onClick={handleClick}>
      跳转到关于页面
    </button>
  );
}

与浏览器原生的window.location.href赋值不同,使用useRouterpush方法不会导致整个页面的完全重加载,这对性能更加有利。

App Router:面向未来的新范式

基本结构

App Router引入了全新的目录结构:

css 复制代码
src/
└── app
    ├── about
    │   └── page.js
    ├── globals.css
    ├── layout.js
    ├── login
    │   └── page.js
    ├── page.js 
    └── team
        └── route.js

创建应用程序的约定如下:

  • 应用中的每个页面都有自己的目录,目录名称定义URL路径
  • 浏览器中访问路径时渲染的组件是page.js
  • 每个页面的目录中可以放置几个具有保留名称的文件,如loading.jstemplate.jslayout.js

核心特性

服务器组件与客户端组件

App Router中最重大的变化是:默认情况下,应用程序目录中的任何组件都是服务器组件。这意味着:

  • 服务器组件在服务器上呈现,所有代码都保留在服务器上
  • 不能使用客户端功能如window对象或React中的典型钩子
  • 可以通过在文件顶部声明"use client"来声明客户端组件

布局系统

App Router原生支持布局,通过layout.js文件实现。布局组件可以应用于多个页面,如果子目录没有单独指定布局,则使用顶级布局。

jsx 复制代码
// layout.js
export default function LoginLayout({ children }) {
  return <div className='login-area'>{children}</div>
}

布局会自动应用于其下的所有页面,无需在页面文件中额外指定。

数据获取

App Router引入了组件级数据获取,与Pages Router的页面级数据获取形成鲜明对比。在Server Component中可以直接使用async/await和fetch:

jsx 复制代码
async function BlogPost({ slug }) {
  const post = await fetch(`/api/posts/${slug}`).then(res => res.json());
  
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

深度对比:Pages Router vs App Router

功能特性对比

特性 Pages Router App Router
默认组件类型 客户端组件 服务器组件
思维模式 "客户端优先" "服务器优先"
数据获取 页面级别,集中在getStaticProps/getServerSideProps中 组件级别,在各个Server Component内部
布局系统 通过_app.js和getLayout模式实现,非原生 原生支持,文件系统结构天然支持嵌套
客户端JS 整个页面的所有组件代码都会被发送到客户端 只有标记为"use client"的组件及其子组件的JS会被发送

性能对比

在性能方面,App Router的架构优势是压倒性的。通过默认使用Server Components,它从根本上解决了客户端JavaScript过大的问题。

学习曲线与生态系统

  • Pages Router:生态系统极其成熟,学习曲线较低,对于有React SPA经验的开发者来说非常熟悉

  • App Router:生态系统正在快速发展中,学习曲线较高,需要理解Server/Client组件的区别等新概念

决策指南:如何选择?

选择 App Router,如果:

  • ✅ 你正在开始一个全新的项目,没有历史包袱
  • ✅ 性能是你的首要考量,你希望从一开始就构建最快、最轻量的应用
  • ✅ 你的应用有复杂的、嵌套的布局和数据依赖关系
  • ✅ 你的团队乐于学习和拥抱新技术
  • ✅ 你正在构建一个数据密集型、内容驱动的应用(如仪表盘、电商网站、CMS前端)

选择 Pages Router,如果:

  • 🟡 你正在维护或迭代一个现有的、基于Pages Router的项目
  • 🟡 你的项目高度依赖某个尚未完全支持App Router的第三方库
  • 🟡 团队成员对RSC不熟悉,且项目交付时间非常紧张
  • 🟡 你的应用是一个非常简单、以交互为主的轻量级SPA,服务端渲染的需求很低

混合模式的可能性

Next.js允许你在同一个项目中同时使用apppages目录。这为渐进式迁移提供了一条平滑的路径。你可以先在现有项目中引入app目录来开发新功能,逐步体验App Router的优势。

实战建议

从Pages Router迁移到App Router

如果你计划从Pages Router迁移到App Router,可以考虑以下步骤:

  1. 逐步迁移:利用混合模式,逐步将页面从pages目录迁移到app目录
  2. 组件适配:将使用React钩子或浏览器API的组件标记为客户端组件
  3. 数据获取:将getStaticProps/getServerSideProps重构为组件级数据获取
  4. 布局重构:利用App Router的布局系统简化你的布局代码

开发技巧

  1. 明确组件边界:在App Router中,要清晰界定服务器组件和客户端组件的职责
  2. 利用流式渲染:App Router支持流式渲染,可以显著提升用户体验
  3. 合理使用缓存:App Router提供了更精细的缓存控制机制

结语

App Router无疑是Next.js的未来。它通过React Server Components带来的架构革新,在性能、代码组织和开发体验上都提供了巨大的飞跃。对于新项目,除非有特定的生态限制,否则强烈建议从App Router开始。

希望这篇文章能帮助你理解Next.js中两种路由系统的区别,如果你有任何问题,欢迎在评论区留言讨论!


作者:大鱼,前端开发者,专注于大前端圈技术栈。欢迎关注我的微信公众号<大前端历险记>获取更多前端技术干货。

相关推荐
xun_xing2 小时前
基于Nextjs15的学习手记
前端·javascript·react.js
有意义2 小时前
Vibe Coding:人机共生时代的开发革命 —— 从概念到 Chrome 扩展实战
前端·ai编程·vibecoding
梅梅绵绵冰2 小时前
SpringMVC快速入门
前端
kirkWang2 小时前
HarmonyOS 6.0 服务卡片实战:把「轻食刻」装进桌面,让轻断食一眼可控
前端
1024小神2 小时前
VNBarcodeObservation的结果中observation.boundingBox 是什么类型?
前端
xun_xing2 小时前
Javascript的Iterator和Generator
前端·javascript
秃了才能变得更强2 小时前
React Native 新、旧架构集成原生模块方式
前端
1024小神2 小时前
swift中VNDetectBarcodesRequest VNImageRequestHandler 是什么?有什么作用?VN是什么意思
前端
加个鸡腿儿2 小时前
React项目实战 | 修复Table可展开行,点击一个全部展开
前端·react.js·编程语言