Next.js 提供了两种主要的路由架构:Pages Router 和 App Router。它们在设计理念、功能和性能方面有显著差异。
Pages Router
Pages Router 是 Next.js 的传统路由系统,基于 pages 目录。
特点
- 文件结构简单
shellpages/ index.js about.js blog/ [slug].js
- 数据获取方法
getStaticProps:静态生成时获取数据getServerSideProps:每次请求时获取数据getStaticPaths:定义动态路由的路径
- 生命周期
- 支持 React 的完整生命周期
- 使用
useEffect进行客户端数据获取
- 路由钩子
javascriptimport { useRouter } from 'next/router'; const router = useRouter(); console.log(router.pathname, router.query);
优点
- 成熟稳定,文档和社区支持完善
- 学习曲线较平缓
- 适合中小型项目
缺点
- 不支持嵌套路由
- 不支持服务器组件
- 性能优化有限
App Router
App Router 是 Next.js 13+ 引入的新路由系统,基于 app 目录。
特点
- 文件结构
shellapp/ page.js layout.js about/ page.js blog/ [slug]/ page.js
- 服务器组件和客户端组件
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>; }
- 数据获取
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>; }
- 布局系统
javascript// app/layout.js export default function RootLayout({ children }) { return ( <html> <body> <Header /> {children} <Footer /> </body> </html> ); }
- 路由钩子
javascriptimport { useParams, usePathname } from 'next/navigation'; const params = useParams(); const pathname = usePathname();
优点
- 支持服务器组件,减少客户端 JavaScript
- 支持嵌套路由和布局
- 更好的性能和用户体验
- 更现代的 API 设计
缺点
- 学习曲线较陡峭
- 相对较新,生态系统还在发展
- 需要理解服务器组件和客户端组件的区别
主要区别对比
| 特性 | Pages Router | App Router |
|---|---|---|
| 目录 | pages/ | app/ |
| 服务器组件 | 不支持 | 支持 |
| 嵌套路由 | 不支持 | 支持 |
| 布局系统 | 有限 | 强大 |
| 数据获取 | getStaticProps/getServerSideProps | 直接在组件中 |
| 路由钩子 | next/router | next/navigation |
| 文件约定 | index.js | page.js |
| 加载状态 | 需要手动实现 | 自动支持 loading.js |
| 错误处理 | 需要手动实现 | 自动支持 error.js |
| 流式渲染 | 不支持 | 支持 |
迁移建议
何时使用 Pages Router
- 现有项目已经在使用 Pages Router
- 项目规模较小,不需要复杂的功能
- 团队对 Pages Router 更熟悉
何时使用 App Router
- 新项目
- 需要服务器组件来优化性能
- 需要嵌套路由和复杂布局
- 需要更好的 SEO 和性能
混合使用
Next.js 允许同时使用两种路由器:
pages/目录使用 Pages Routerapp/目录使用 App Router
javascript// 两个目录可以共存 pages/ api/ hello.js // API 路由 app/ page.js // 主页面
最佳实践
- 新项目优先使用 App Router:获得更好的性能和开发体验
- 逐步迁移:现有项目可以逐步将页面迁移到 App Router
- 合理使用服务器组件:将不需要交互的组件设为服务器组件
- 利用布局系统:使用嵌套布局来共享 UI
- 保持一致性:在一个项目中尽量统一使用一种路由器
选择哪种路由器取决于项目需求、团队经验和性能要求。App Router 代表了 Next.js 的未来方向,但 Pages Router 仍然是可靠的选择。