
文章目录
-
- 一、文件系统路由核心概念
-
- [1.1 什么是文件系统路由?](#1.1 什么是文件系统路由?)
- [1.2 工作原理架构图](#1.2 工作原理架构图)
- 二、基础路由配置
-
- [2.1 静态路由](#2.1 静态路由)
- [2.2 路由映射关系表](#2.2 路由映射关系表)
- 三、动态路由详解
-
- [3.1 基础动态路由](#3.1 基础动态路由)
- [3.2 可选捕获所有段路由](#3.2 可选捕获所有段路由)
- 四、路由参数与数据获取
-
- [4.1 预渲染数据获取](#4.1 预渲染数据获取)
- [4.2 路由查询参数处理](#4.2 路由查询参数处理)
- 五、路由导航与链接
-
- [5.1 客户端导航](#5.1 客户端导航)
- [5.2 编程式导航](#5.2 编程式导航)
- [5.3 路由事件监听](#5.3 路由事件监听)
- 六、高级路由模式
-
- [6.1 并行路由和拦截路由](#6.1 并行路由和拦截路由)
- [6.2 动态导入与路由分组](#6.2 动态导入与路由分组)
- [6.3 中间件与路由保护](#6.3 中间件与路由保护)
- 七、路由优化策略
-
- [7.1 预加载策略](#7.1 预加载策略)
- [7.2 滚动恢复与保持](#7.2 滚动恢复与保持)
- [八、API 路由系统](#八、API 路由系统)
-
- [8.1 基础API路由](#8.1 基础API路由)
- [8.2 动态API路由](#8.2 动态API路由)
- 九、最佳实践与常见问题
-
- [9.1 路由组织结构最佳实践](#9.1 路由组织结构最佳实践)
- [9.2 常见问题与解决方案](#9.2 常见问题与解决方案)
- 十、性能优化与监控
-
- [10.1 路由性能监控](#10.1 路由性能监控)
- [10.2 路由缓存策略](#10.2 路由缓存策略)
- 总结
一、文件系统路由核心概念
1.1 什么是文件系统路由?
文件系统路由是 Next.js 的核心特性之一,它通过文件目录结构自动生成应用的路由系统。这意味着文件即路由,无需手动配置路由表。
📁 pages/
├── index.js → https://example.com/
├── about.js → https://example.com/about
├── blog/
│ ├── index.js → https://example.com/blog
│ └── [slug].js → https://example.com/blog/:slug
└── api/
└── users.js → https://example.com/api/users
1.2 工作原理架构图
┌─────────────────────────────────────────────┐
│ 文件系统路由工作流程 │
├─────────────────────────────────────────────┤
│ 1. 文件创建于 pages/ 目录 │
│ 2. Next.js 编译时扫描目录结构 │
│ 3. 生成路由映射表 │
│ 4. 创建对应的 React 组件 │
│ 5. 建立 URL 与组件的映射关系 │
│ 6. 请求时匹配并渲染对应组件 │
└─────────────────────────────────────────────┘
二、基础路由配置
2.1 静态路由
基本页面创建:
javascript
// pages/index.js - 首页路由
export default function HomePage() {
return <h1>欢迎访问首页</h1>;
}
// pages/about.js - 关于页面
export default function AboutPage() {
return (
<div>
<h1>关于我们</h1>
<p>这是关于页面内容</p>
</div>
);
}
// pages/contact.js - 联系页面
export default function ContactPage() {
return (
<div>
<h1>联系我们</h1>
<form>
<input type="email" placeholder="邮箱" />
<button type="submit">发送</button>
</form>
</div>
);
}
嵌套文件夹路由:
javascript
// pages/products/index.js - 产品列表页
export default function ProductsPage() {
return (
<div>
<h1>所有产品</h1>
<ul>
<li>产品1</li>
<li>产品2</li>
</ul>
</div>
);
}
// pages/products/featured.js - 特色产品页
export default function FeaturedProducts() {
return <h1>特色产品</h1>;
}
2.2 路由映射关系表
| 文件路径 | 路由URL | 访问方式 |
|---|---|---|
pages/index.js |
/ |
自动生成 |
pages/about.js |
/about |
自动生成 |
pages/blog/index.js |
/blog |
自动生成 |
pages/blog/first-post.js |
/blog/first-post |
自动生成 |
pages/products/categories/index.js |
/products/categories |
自动生成 |
三、动态路由详解
3.1 基础动态路由
单参数动态路由:
javascript
// pages/products/[id].js
import { useRouter } from 'next/router';
export default function ProductDetail() {
const router = useRouter();
const { id } = router.query;
return (
<div>
<h1>产品详情页</h1>
<p>产品ID: {id}</p>
<p>产品名称: 产品{id}</p>
</div>
);
}
// 访问示例:
// /products/123 → id = "123"
// /products/abc → id = "abc"
多段动态路由:
javascript
// pages/category/[categoryId]/product/[productId].js
export default function CategoryProductDetail() {
const router = useRouter();
const { categoryId, productId } = router.query;
return (
<div>
<h1>分类产品详情</h1>
<p>分类ID: {categoryId}</p>
<p>产品ID: {productId}</p>
</div>
);
}
// 访问示例:
// /category/electronics/product/iphone-13
3.2 可选捕获所有段路由
捕获所有路由:
javascript
// pages/docs/[...slug].js
export default function DocsPage() {
const router = useRouter();
const { slug = [] } = router.query;
return (
<div>
<h1>文档页面</h1>
<p>路径参数: {JSON.stringify(slug)}</p>
<p>当前路径: /docs/{slug.join('/')}</p>
</div>
);
}
// 访问示例:
// /docs/getting-started → slug = ["getting-started"]
// /docs/api/v1/users → slug = ["api", "v1", "users"]
可选捕获所有路由:
javascript
// pages/blog/[[...slug]].js
export default function BlogPage() {
const router = useRouter();
const { slug } = router.query;
return (
<div>
<h1>博客页面</h1>
{slug ? (
<p>查看具体文章: {slug.join('/')}</p>
) : (
<p>博客首页 - 显示所有文章</p>
)}
</div>
);
}
// 访问示例:
// /blog → 显示博客首页
// /blog/react-tutorial → 显示具体文章
// /blog/category/tutorials → 显示分类文章
四、路由参数与数据获取
4.1 预渲染数据获取
getStaticPaths + getStaticProps(SSG):
javascript
// pages/products/[id].js
import { useRouter } from 'next/router';
// 1. 定义所有可能的路径
export async function getStaticPaths() {
// 在实际应用中,这里从数据库或API获取产品列表
const products = [
{ id: '1', name: '笔记本电脑' },
{ id: '2', name: '智能手机' },
{ id: '3', name: '平板电脑' },
];
const paths = products.map(product => ({
params: { id: product.id.toString() }
}));
return {
paths,
fallback: true // 或 false 或 'blocking'
};
}
// 2. 获取页面数据
export async function getStaticProps({ params }) {
const productId = params.id;
// 模拟API调用
const product = {
id: productId,
name: `产品${productId}`,
description: `这是产品${productId}的详细描述`,
price: 1000 + parseInt(productId) * 100,
};
return {
props: {
product
},
revalidate: 60 // ISR: 每60秒重新生成
};
}
// 3. 页面组件
export default function ProductDetail({ product }) {
const router = useRouter();
// 如果页面正在生成,显示加载状态
if (router.isFallback) {
return <div>加载中...</div>;
}
return (
<div>
<h1>{product.name}</h1>
<p>{product.description}</p>
<p>价格: ¥{product.price}</p>
</div>
);
}
getServerSideProps(SSR):
javascript
// pages/user/[userId].js
export async function getServerSideProps(context) {
const { params, req, res, query } = context;
const { userId } = params;
// 获取用户信息(服务端执行)
const userResponse = await fetch(`https://api.example.com/users/${userId}`);
const user = await userResponse.json();
// 获取用户订单(依赖用户信息)
const ordersResponse = await fetch(`https://api.example.com/users/${userId}/orders`);
const orders = await ordersResponse.json();
return {
props: {
user,
orders,
timestamp: new Date().toISOString()
}
};
}
export default function UserProfile({ user, orders, timestamp }) {
return (
<div>
<h1>{user.name} 的个人资料</h1>
<p>邮箱: {user.email}</p>
<p>注册时间: {user.createdAt}</p>
<h2>订单列表</h2>
<ul>
{orders.map(order => (
<li key={order.id}>
订单 #{order.id} - ¥{order.amount}
</li>
))}
</ul>
<p>页面生成时间: {timestamp}</p>
</div>
);
}
4.2 路由查询参数处理
javascript
// pages/search/index.js
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
export default function SearchPage() {
const router = useRouter();
const { query, category, sort } = router.query;
const [results, setResults] = useState([]);
// 获取搜索结果
useEffect(() => {
if (query) {
fetchResults(query, category, sort);
}
}, [query, category, sort]);
const fetchResults = async (query, category, sort) => {
// 构建搜索URL
const params = new URLSearchParams();
if (query) params.append('q', query);
if (category) params.append('category', category);
if (sort) params.append('sort', sort);
const response = await fetch(`/api/search?${params}`);
const data = await response.json();
setResults(data);
};
const handleSearch = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const searchQuery = formData.get('query');
// 更新URL,触发路由变化
router.push({
pathname: '/search',
query: { query: searchQuery }
});
};
return (
<div>
<form onSubmit={handleSearch}>
<input
name="query"
defaultValue={query || ''}
placeholder="搜索..."
/>
<button type="submit">搜索</button>
</form>
<div>
<h2>搜索结果</h2>
<ul>
{results.map(result => (
<li key={result.id}>{result.title}</li>
))}
</ul>
</div>
</div>
);
}
五、路由导航与链接
5.1 客户端导航
基础导航:
javascript
import Link from 'next/link';
export default function Navigation() {
return (
<nav>
<ul style={{ display: 'flex', gap: '20px' }}>
<li>
<Link href="/">
<a>首页</a>
</Link>
</li>
<li>
<Link href="/about">
<a>关于</a>
</Link>
</li>
<li>
<Link href="/products">
<a>产品</a>
</Link>
</li>
<li>
<Link href="/blog">
<a>博客</a>
</Link>
</li>
</ul>
</nav>
);
}
动态路由导航:
javascript
import Link from 'next/link';
export default function ProductList({ products }) {
return (
<div>
<h1>产品列表</h1>
<ul>
{products.map(product => (
<li key={product.id}>
<Link href={`/products/${product.id}`}>
<a>{product.name}</a>
</Link>
<br />
<Link href={{
pathname: '/products/[id]',
query: { id: product.id }
}}>
<a>(另一种写法)</a>
</Link>
</li>
))}
</ul>
</div>
);
}
5.2 编程式导航
javascript
import { useRouter } from 'next/router';
import { useState } from 'react';
export default function LoginPage() {
const router = useRouter();
const [loading, setLoading] = useState(false);
const handleLogin = async () => {
setLoading(true);
// 模拟登录API调用
setTimeout(() => {
// 登录成功后重定向
router.push('/dashboard');
}, 1000);
};
const handleGoBack = () => {
// 返回上一页
router.back();
};
const handleReplace = () => {
// 替换当前历史记录
router.replace('/profile');
};
return (
<div>
<h1>登录页面</h1>
<button onClick={handleLogin} disabled={loading}>
{loading ? '登录中...' : '登录'}
</button>
<button onClick={handleGoBack}>返回</button>
<button onClick={handleReplace}>替换到个人资料</button>
{/* 监听路由变化 */}
<p>当前路由: {router.pathname}</p>
</div>
);
}
5.3 路由事件监听
javascript
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export default function RouteTracker() {
const router = useRouter();
useEffect(() => {
const handleRouteChangeStart = (url) => {
console.log('路由开始变化:', url);
// 显示加载指示器
};
const handleRouteChangeComplete = (url) => {
console.log('路由变化完成:', url);
// 隐藏加载指示器
};
const handleRouteChangeError = (err, url) => {
console.error('路由变化错误:', err, '目标URL:', url);
};
// 添加事件监听器
router.events.on('routeChangeStart', handleRouteChangeStart);
router.events.on('routeChangeComplete', handleRouteChangeComplete);
router.events.on('routeChangeError', handleRouteChangeError);
// 清理事件监听器
return () => {
router.events.off('routeChangeStart', handleRouteChangeStart);
router.events.off('routeChangeComplete', handleRouteChangeComplete);
router.events.off('routeChangeError', handleRouteChangeError);
};
}, [router]);
return (
<div>
<h1>路由跟踪器</h1>
<p>打开控制台查看路由事件</p>
</div>
);
}
六、高级路由模式
6.1 并行路由和拦截路由
拦截路由(Next.js 13+ App Router):
javascript
// app/@modal/default.js - 模态框的默认状态(不显示)
export default function Default() {
return null;
}
// app/@modal/(.)login/page.js - 拦截登录页,以模态框形式显示
'use client';
import { useRouter } from 'next/navigation';
import LoginForm from '@/components/LoginForm';
export default function InterceptedLogin() {
const router = useRouter();
const handleClose = () => {
router.back();
};
return (
<div className="modal-overlay">
<div className="modal-content">
<button onClick={handleClose}>关闭</button>
<LoginForm />
</div>
</div>
);
}
// app/layout.js - 根布局
export default function RootLayout({ children, modal }) {
return (
<html>
<body>
{children}
{modal}
</body>
</html>
);
}
6.2 动态导入与路由分组
路由分组(组织相关路由):
pages/
├── (auth)/
│ ├── login.js
│ └── register.js
├── (shop)/
│ ├── products/
│ └── cart/
└── (admin)/
├── dashboard/
└── users/
动态导入组件:
javascript
// 使用 dynamic import 实现路由分割
import dynamic from 'next/dynamic';
import { Suspense } from 'react';
// 动态导入组件,按需加载
const HeavyComponent = dynamic(() => import('@/components/HeavyComponent'), {
loading: () => <p>加载中...</p>,
ssr: false, // 禁用服务端渲染
});
const MapComponent = dynamic(() => import('@/components/MapComponent'), {
loading: () => <p>地图加载中...</p>,
suspense: true,
});
export default function ComplexPage() {
return (
<div>
<h1>复杂页面</h1>
{/* 普通动态导入 */}
<HeavyComponent />
{/* 使用 Suspense 的动态导入 */}
<Suspense fallback={<p>加载地图组件...</p>}>
<MapComponent />
</Suspense>
</div>
);
}
6.3 中间件与路由保护
路由中间件:
javascript
// middleware.js
import { NextResponse } from 'next/server';
import { verifyToken } from './lib/auth';
export async function middleware(request) {
const token = request.cookies.get('auth-token');
const { pathname } = request.nextUrl;
// 保护需要认证的路由
const protectedRoutes = ['/dashboard', '/profile', '/settings'];
const isProtectedRoute = protectedRoutes.some(route =>
pathname.startsWith(route)
);
if (isProtectedRoute && !token) {
// 重定向到登录页
const url = request.nextUrl.clone();
url.pathname = '/login';
url.searchParams.set('redirect', pathname);
return NextResponse.redirect(url);
}
// 如果已登录,重定向登录页到首页
if (pathname === '/login' && token) {
return NextResponse.redirect(new URL('/', request.url));
}
// 添加自定义header
const response = NextResponse.next();
response.headers.set('x-custom-header', 'custom-value');
return response;
}
// 配置中间件匹配规则
export const config = {
matcher: [
/*
* 匹配所有请求路径,除了:
* - api (API路由)
* - _next/static (静态文件)
* - _next/image (图片优化)
* - favicon.ico (网站图标)
* - public文件夹
*/
'/((?!api|_next/static|_next/image|favicon.ico|public/).*)',
],
};
七、路由优化策略
7.1 预加载策略
javascript
import Link from 'next/link';
export default function NavigationWithPrefetch() {
return (
<nav>
<ul>
<li>
{/* 默认预加载(视口内链接) */}
<Link href="/">
<a>首页</a>
</Link>
</li>
<li>
{/* 禁用预加载 */}
<Link href="/about" prefetch={false}>
<a>关于</a>
</Link>
</li>
<li>
{/* 手动触发预加载 */}
<Link href="/contact">
<a
onMouseEnter={() => {
// 手动预加载
import('next/link').then(Link => {
// 预加载逻辑
});
}}
>
联系我们
</a>
</Link>
</li>
</ul>
</nav>
);
}
7.2 滚动恢复与保持
javascript
// 自定义滚动行为
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export default function ScrollRestoration() {
const router = useRouter();
useEffect(() => {
const handleRouteChange = () => {
// 保存当前滚动位置
sessionStorage.setItem(
`scrollPos:${router.asPath}`,
JSON.stringify({ x: window.scrollX, y: window.scrollY })
);
};
const restoreScrollPosition = () => {
const scrollPos = sessionStorage.getItem(`scrollPos:${router.asPath}`);
if (scrollPos) {
const { x, y } = JSON.parse(scrollPos);
window.scrollTo(x, y);
}
};
router.events.on('routeChangeStart', handleRouteChange);
router.events.on('routeChangeComplete', restoreScrollPosition);
return () => {
router.events.off('routeChangeStart', handleRouteChange);
router.events.off('routeChangeComplete', restoreScrollPosition);
};
}, [router]);
return null;
}
八、API 路由系统
8.1 基础API路由
javascript
// pages/api/users.js
export default function handler(req, res) {
const { method } = req;
switch (method) {
case 'GET':
return handleGet(req, res);
case 'POST':
return handlePost(req, res);
case 'PUT':
return handlePut(req, res);
case 'DELETE':
return handleDelete(req, res);
default:
res.setHeader('Allow', ['GET', 'POST', 'PUT', 'DELETE']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}
async function handleGet(req, res) {
// 查询参数
const { limit = 10, offset = 0 } = req.query;
// 模拟数据库查询
const users = Array.from({ length: 50 }, (_, i) => ({
id: i + 1,
name: `用户${i + 1}`,
email: `user${i + 1}@example.com`,
}));
const paginatedUsers = users.slice(
parseInt(offset),
parseInt(offset) + parseInt(limit)
);
res.status(200).json({
success: true,
data: paginatedUsers,
pagination: {
total: users.length,
limit: parseInt(limit),
offset: parseInt(offset),
}
});
}
async function handlePost(req, res) {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({
success: false,
error: '缺少必要字段'
});
}
// 模拟创建用户
const newUser = {
id: Date.now(),
name,
email,
createdAt: new Date().toISOString(),
};
res.status(201).json({
success: true,
data: newUser,
});
}
// 其他处理函数...
8.2 动态API路由
javascript
// pages/api/users/[userId].js
import { createRouter } from 'next-connect';
import { getConnection } from '../../lib/database';
const router = createRouter();
// GET /api/users/:userId
router.get(async (req, res) => {
const { userId } = req.query;
const db = await getConnection();
try {
const user = await db.collection('users').findOne({
_id: new ObjectId(userId)
});
if (!user) {
return res.status(404).json({
success: false,
error: '用户不存在'
});
}
res.status(200).json({ success: true, data: user });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// PUT /api/users/:userId
router.put(async (req, res) => {
const { userId } = req.query;
const updateData = req.body;
const db = await getConnection();
try {
const result = await db.collection('users').updateOne(
{ _id: new ObjectId(userId) },
{ $set: updateData }
);
if (result.matchedCount === 0) {
return res.status(404).json({
success: false,
error: '用户不存在'
});
}
const updatedUser = await db.collection('users').findOne({
_id: new ObjectId(userId)
});
res.status(200).json({ success: true, data: updatedUser });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// DELETE /api/users/:userId
router.delete(async (req, res) => {
const { userId } = req.query;
const db = await getConnection();
try {
const result = await db.collection('users').deleteOne({
_id: new ObjectId(userId)
});
if (result.deletedCount === 0) {
return res.status(404).json({
success: false,
error: '用户不存在'
});
}
res.status(204).end();
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
export default router.handler();
九、最佳实践与常见问题
9.1 路由组织结构最佳实践
pages/
├── index.js # 首页
├── _app.js # 自定义App
├── _document.js # 自定义Document
├── api/ # API路由
│ ├── auth/ # 认证相关
│ │ ├── login.js
│ │ ├── logout.js
│ │ └── register.js
│ ├── users/ # 用户相关
│ │ ├── index.js
│ │ └── [id].js
│ └── products/ # 产品相关
│ ├── index.js
│ └── [id].js
├── auth/ # 认证页面
│ ├── login.js
│ └── register.js
├── dashboard/ # 仪表板(需要认证)
│ ├── index.js
│ ├── settings.js
│ └── analytics.js
├── products/ # 产品页面
│ ├── index.js # 产品列表
│ ├── [category]/ # 按分类
│ │ └── index.js
│ └── [id]/ # 产品详情
│ └── index.js
├── blog/ # 博客
│ ├── index.js # 博客列表
│ ├── [year]/ # 按年份归档
│ │ ├── index.js
│ │ └── [month]/
│ │ └── index.js
│ └── [slug].js # 博客文章
└── legal/ # 法律页面
├── terms.js # 服务条款
└── privacy.js # 隐私政策
9.2 常见问题与解决方案
问题1:路由404错误
javascript
// 解决方案:自定义404页面
// pages/404.js
export default function Custom404() {
return (
<div style={{ textAlign: 'center', padding: '50px' }}>
<h1>404 - 页面未找到</h1>
<p>抱歉,您访问的页面不存在</p>
<Link href="/">
<a>返回首页</a>
</Link>
</div>
);
}
问题2:动态路由参数类型错误
javascript
// pages/products/[id].js
export async function getStaticPaths() {
return {
paths: [],
fallback: 'blocking', // 使用blocking模式
};
}
export async function getStaticProps({ params }) {
const productId = parseInt(params.id);
if (isNaN(productId)) {
return {
notFound: true, // 返回404
};
}
// ... 获取数据
}
问题3:路由过渡动画
javascript
// 使用Framer Motion实现路由过渡
import { motion, AnimatePresence } from 'framer-motion';
import { useRouter } from 'next/router';
export default function Layout({ children }) {
const router = useRouter();
return (
<AnimatePresence mode="wait">
<motion.div
key={router.route}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.3 }}
>
{children}
</motion.div>
</AnimatePresence>
);
}
十、性能优化与监控
10.1 路由性能监控
javascript
// lib/performance.js
export function trackRoutePerformance() {
if (typeof window !== 'undefined' && 'performance' in window) {
const navigationTiming = performance.getEntriesByType('navigation')[0];
const metrics = {
dnsTime: navigationTiming.domainLookupEnd - navigationTiming.domainLookupStart,
tcpTime: navigationTiming.connectEnd - navigationTiming.connectStart,
requestTime: navigationTiming.responseEnd - navigationTiming.requestStart,
domContentLoaded: navigationTiming.domContentLoadedEventEnd - navigationTiming.fetchStart,
fullLoadTime: navigationTiming.loadEventEnd - navigationTiming.fetchStart,
};
// 发送到监控服务
sendToAnalytics(metrics);
}
}
// _app.js
import App from 'next/app';
import { trackRoutePerformance } from '../lib/performance';
import Router from 'next/router';
Router.events.on('routeChangeComplete', trackRoutePerformance);
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
10.2 路由缓存策略
javascript
// 自定义缓存策略
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export default function RouteCacheManager() {
const router = useRouter();
useEffect(() => {
// 预取重要路由
const prefetchRoutes = ['/dashboard', '/profile', '/settings'];
prefetchRoutes.forEach(route => {
router.prefetch(route);
});
// 管理路由缓存
const cache = new Map();
const handleRouteChange = (url) => {
// 缓存当前页面数据
cache.set(router.asPath, {
timestamp: Date.now(),
scrollPosition: window.scrollY,
});
// 清理过期缓存(超过5分钟)
const now = Date.now();
for (const [key, value] of cache.entries()) {
if (now - value.timestamp > 5 * 60 * 1000) {
cache.delete(key);
}
}
};
router.events.on('routeChangeStart', handleRouteChange);
return () => {
router.events.off('routeChangeStart', handleRouteChange);
};
}, [router]);
return null;
}
总结
Next.js 的文件系统路由是一个强大而灵活的特性,它通过简单的文件结构提供了完整的路由解决方案。关键要点包括:
- 约定优于配置:通过文件系统自动生成路由,减少样板代码
- 多种路由类型:支持静态路由、动态路由、可选路由等
- 预渲染支持:无缝集成 SSG 和 SSR 数据获取
- API 路由集成:前后端同构开发体验
- 性能优化:自动代码分割、预加载、路由过渡
通过合理利用文件系统路由的特性,可以构建出高性能、可维护的现代 Web 应用。无论是简单的静态网站还是复杂的企业级应用,Next.js 的路由系统都能提供合适的解决方案。