在现代 Web 应用的世界里,路由 是城市道路,中间件 是守在路口的警察,确保一切交通有序、安全。
Next.js 则是那位既懂交通规则、又能修路铺桥的工程师------你不仅可以在它的路网上自由嵌套路线,还可以让中间件在用户抵达目的地前对他们的身份、行李、甚至心情(如果你愿意)做检查。
一、嵌套路由的本质
在 Next.js 中,文件即路由的哲学让你少了很多配置文件的负担,但当你需要结构化复杂页面时,嵌套路由就派上了用场。
比如,你有一个博客系统:
bash
/app
/blog
/page.js
/[slug]
/page.js
/blog
→ 博客列表页/blog/[slug]
→ 某篇博客详情页
底层原理:
- Next.js 会遍历
app
目录下的文件夹结构。 - 目录名映射为 URL 路径,
[param]
形式表示动态路由。 - 嵌套文件夹会形成嵌套路由,父级路由可以包含 Layout,用来统一头部、底部、导航栏。
Layout 嵌套机制
javascript
// app/blog/layout.js
export default function BlogLayout({ children }) {
return (
<div>
<header>Blog Header</header>
<main>{children}</main>
</div>
);
}
这样 /blog
和 /blog/[slug]
都会共享这个 BlogLayout
,底层是组件树递归渲染,Next.js 会为每一层 Layout 建立独立 React 节点,从而实现父子关系。
二、中间件(Middleware)的使命
想象一下你有一个高档餐厅(网站),中间件就是门口的保安------
- 检查身份证(鉴权)
- 检查预订记录(权限控制)
- 检查是否穿正装(条件跳转)
- 甚至可以把迟到的人送去别的餐厅(重定向)
中间件的运行时机
- 在 请求到达页面组件之前。
- 运行在 Edge Runtime(轻量、低延迟,全球分布)。
- 可以读取和修改请求、响应。
底层机制:
- 你在项目根目录(或子目录)下放置一个
middleware.js
文件。 - Next.js 会在构建时将它编译为 Edge Function。
- 每次请求进入匹配的路径时,都会先经过中间件逻辑。
三、实战:嵌套路由 + 中间件
假设你有一个 /dashboard
路由和它的嵌套页面 /dashboard/settings
,你想在用户进入这些页面前检查是否已登录。
目录结构:
bash
/app
/dashboard
/page.js
/settings
/page.js
/middleware.js
中间件示例:
javascript
// middleware.js
import { NextResponse } from 'next/server';
export function middleware(req) {
const token = req.cookies.get('token');
if (!token) {
// 未登录则跳转到登录页
return NextResponse.redirect(new URL('/login', req.url));
}
// 已登录则放行
return NextResponse.next();
}
// 限制中间件只匹配 dashboard 路由
export const config = {
matcher: ['/dashboard/:path*']
};
四、嵌套路由与中间件的协作
嵌套路由提供结构化的页面层级 ,而中间件提供请求入口的守卫 。
就像机场一样:
- 嵌套路由 → 航站楼结构(国际、国内、贵宾厅等分区)
- 中间件 → 安检口(拦截违禁品、核对身份、放行)
好处:
- 安全:中间件阻挡未授权用户。
- 体验:减少无意义的页面渲染。
- 性能:Edge Runtime 在边缘节点直接处理,不必每次回到主服务器。
五、最佳实践建议
-
中间件逻辑要精简
- 它运行在边缘节点,不适合做大量计算。
- 适合做快速判断、重定向、设置 cookie。
-
嵌套路由中 Layout 复用 UI
- 避免重复代码,让不同子页面共享样式和结构。
-
分层控制
- 根目录
middleware.js
管全局规则。 - 子目录
middleware.js
处理局部规则(Next.js 13+ 支持子目录中间件)。
- 根目录
六、幽默的尾声
嵌套路由像一座大厦的楼层结构,
中间件是大门口的保安,
而 Next.js 是那位能帮你造大厦、请保安、装电梯的承包商。
有人会问:
"那如果我没中间件,直接让所有人进来会怎样?"
------那就像把你家 Wi-Fi 密码贴在电梯里,很快就会发现隔壁邻居比你还熟悉你的路由结构。