乐闻世界logo
搜索文章和话题

Next.js 的 Pages Router 和 App Router 有什么区别?

2月17日 23:32

Next.js 提供了两种主要的路由架构:Pages Router 和 App Router。它们在设计理念、功能和性能方面有显著差异。

Pages Router

Pages Router 是 Next.js 的传统路由系统,基于 pages 目录。

特点

  1. 文件结构简单
shell
pages/ index.js about.js blog/ [slug].js
  1. 数据获取方法
  • getStaticProps:静态生成时获取数据
  • getServerSideProps:每次请求时获取数据
  • getStaticPaths:定义动态路由的路径
  1. 生命周期
  • 支持 React 的完整生命周期
  • 使用 useEffect 进行客户端数据获取
  1. 路由钩子
javascript
import { useRouter } from 'next/router'; const router = useRouter(); console.log(router.pathname, router.query);

优点

  • 成熟稳定,文档和社区支持完善
  • 学习曲线较平缓
  • 适合中小型项目

缺点

  • 不支持嵌套路由
  • 不支持服务器组件
  • 性能优化有限

App Router

App Router 是 Next.js 13+ 引入的新路由系统,基于 app 目录。

特点

  1. 文件结构
shell
app/ page.js layout.js about/ page.js blog/ [slug]/ page.js
  1. 服务器组件和客户端组件
javascript
// 服务器组件(默认) async function BlogList() { const posts = await fetch('https://api.example.com/posts').then(r => r.json()); return <div>{posts.map(post => <Post key={post.id} {...post} />)}</div>; } // 客户端组件 'use client'; import { useState } from 'react'; function InteractiveComponent() { const [count, setCount] = useState(0); return <button onClick={() => setCount(c => c + 1)}>{count}</button>; }
  1. 数据获取
javascript
// 直接在组件中获取数据 async function Page() { const data = await fetch('https://api.example.com/data', { next: { revalidate: 60 } // ISR }).then(r => r.json()); return <div>{data.content}</div>; }
  1. 布局系统
javascript
// app/layout.js export default function RootLayout({ children }) { return ( <html> <body> <Header /> {children} <Footer /> </body> </html> ); }
  1. 路由钩子
javascript
import { useParams, usePathname } from 'next/navigation'; const params = useParams(); const pathname = usePathname();

优点

  • 支持服务器组件,减少客户端 JavaScript
  • 支持嵌套路由和布局
  • 更好的性能和用户体验
  • 更现代的 API 设计

缺点

  • 学习曲线较陡峭
  • 相对较新,生态系统还在发展
  • 需要理解服务器组件和客户端组件的区别

主要区别对比

特性Pages RouterApp Router
目录pages/app/
服务器组件不支持支持
嵌套路由不支持支持
布局系统有限强大
数据获取getStaticProps/getServerSideProps直接在组件中
路由钩子next/routernext/navigation
文件约定index.jspage.js
加载状态需要手动实现自动支持 loading.js
错误处理需要手动实现自动支持 error.js
流式渲染不支持支持

迁移建议

何时使用 Pages Router

  • 现有项目已经在使用 Pages Router
  • 项目规模较小,不需要复杂的功能
  • 团队对 Pages Router 更熟悉

何时使用 App Router

  • 新项目
  • 需要服务器组件来优化性能
  • 需要嵌套路由和复杂布局
  • 需要更好的 SEO 和性能

混合使用

Next.js 允许同时使用两种路由器:

  • pages/ 目录使用 Pages Router
  • app/ 目录使用 App Router
javascript
// 两个目录可以共存 pages/ api/ hello.js // API 路由 app/ page.js // 主页面

最佳实践

  1. 新项目优先使用 App Router:获得更好的性能和开发体验
  2. 逐步迁移:现有项目可以逐步将页面迁移到 App Router
  3. 合理使用服务器组件:将不需要交互的组件设为服务器组件
  4. 利用布局系统:使用嵌套布局来共享 UI
  5. 保持一致性:在一个项目中尽量统一使用一种路由器

选择哪种路由器取决于项目需求、团队经验和性能要求。App Router 代表了 Next.js 的未来方向,但 Pages Router 仍然是可靠的选择。

标签:Next.js