接着上一篇“路由系统:动态路由和路由组”,这篇讲剩下两种——平行路由与拦截路由
3. 平行路由(Parallel Routes)
平行路由是 Next.js 15 中一个非常强大的功能,它允许你在同一个布局中同时或有条件地渲染多个页面。这类似于 Vue 中的插槽功能,非常适合复杂的页面结构。
3.1. 条件渲染
假设你有一个后台管理系统,需要根据用户的登录状态显示不同的页面。你可以使用平行路由来实现:
app
├── layout.js
├── @dashboard
│ └── page.js
└── @login
└── page.js
在 layout.js 中,你可以根据用户的登录状态动态渲染页面:
// app/layout.js
import { useRouter } from "next/router";
export default function Layout({ children }) {
const router = useRouter();
const isLoggedIn = !!router.query.isLoggedIn; // 假设通过 URL 参数判断登录状态
return (
<>
{isLoggedIn ? children : <Login />}
</>
);
}
function Login() {
return <div>请登录</div>;
}
3.2. 独立路由处理
平行路由还可以为每个路由定义独立的加载和错误处理逻辑。例如,你可以为 @dashboard 和 @login 分别定义加载和错误页面:
app
├── layout.js
├── @dashboard
│ ├── loading.js
│ ├── error.js
│ └── page.js
└── @login
├── loading.js
├── error.js
└── page.js
这样,每个路由都可以独立处理加载和错误状态,而不会影响其他路由。
3.3. 子导航
平行路由还可以定义子页面,就像普通的路由一样。例如,你可以在 @dashboard 下添加多个子页面:
app
├── layout.js
├── @dashboard
│ ├── page.js
│ ├── analytics
│ │ └── page.js
│ └── settings
│ └── page.js
└── @login
└── page.js
这些子页面的 URL 会自动映射,例如 /dashboard/analytics 和 /dashboard/settings。
4. 拦截路由(Intercepting Routes)
拦截路由是 Next.js 15 中另一个强大的功能,它允许你在用户访问某个页面之前进行拦截,根据条件重定向到其他页面。这在实现权限控制和登录状态检查时非常有用。
4.1. 未授权跳转
假设你的后台管理系统需要用户登录后才能访问。你可以在 (dashboard) 路由组中添加一个 _middleware.js 文件:
app
├── (dashboard)
│ ├── _middleware.js
│ ├── dashboard
│ │ └── page.js
│ └── settings
│ └── page.js
在 _middleware.js 中,你可以编写如下代码:
// app/(dashboard)/_middleware.js
import { redirect } from "next/navigation";
export async function middleware(request) {
const isLoggedIn = request.cookies.get("isLoggedIn");
if (!isLoggedIn) {
redirect("/login");
}
}
当用户未登录时,访问 (dashboard) 下的任何页面都会被重定向到登录页面。
4.2. 根据用户角色跳转
你还可以根据用户的角色进行跳转。例如,普通用户只能访问普通页面,而管理员可以访问管理页面:
// app/(dashboard)/_middleware.js
import { redirect } from "next/navigation";
export async function middleware(request) {
const isLoggedIn = request.cookies.get("isLoggedIn");
const role = request.cookies.get("role");
if (!isLoggedIn) {
redirect("/login");
}
if (role !== "admin" && request.nextUrl.pathname.startsWith("/admin")) {
redirect("/dashboard");
}
}
当用户访问 /admin 路径下的页面时,如果其角色不是管理员(admin),则会被重定向到 /dashboard 页面。
4.3. 注意事项
- 拦截路由只在服务器端执行,不会影响客户端的性能。
- 在
_middleware.js文件中,你可以通过request对象访问请求信息,例如request.cookies、request.headers等。 - 使用
redirect函数时,可以指定完整的 URL 或相对路径。 _middleware.js文件可以访问request.nextUrl对象,其中包含了当前请求的 URL 信息,例如pathname、search等。
总结
平行路由
- 条件渲染:根据条件动态渲染不同的页面内容,例如根据用户登录状态显示登录页或主页。
- 独立路由处理:为每个路由定义独立的加载和错误处理逻辑,提升用户体验。
- 子导航:为平行路由添加子页面,实现复杂的页面结构,例如后台管理系统的多级菜单。
拦截路由
- 未授权跳转:在用户未登录时重定向到登录页面,实现权限控制。
- 根据用户角色跳转:根据用户的角色重定向到不同的页面,实现更细粒度的权限管理。
实际应用场景
1. 博客网站
- 使用 动态路由:
/blog/[slug],根据文章标题动态加载内容。 - 使用 路由组:
(marketing)和(blog),分别管理营销页面和博客页面。 - 使用 拦截路由:未登录用户访问后台管理页面时重定向到登录页面。
2. 电商网站
- 使用 动态路由:
/shop/[...slug],支持多级商品分类。 - 使用 路由组:
(shop)和(user),分别管理商品页面和用户相关页面。 - 使用 平行路由:在后台管理页面中,根据用户角色显示不同的模块。
3. 后台管理系统
- 使用 动态路由:
/dashboard/[slug],动态加载不同的管理模块。 - 使用 路由组:
(admin)和(user),分别管理管理员和普通用户的页面。 - 使用 拦截路由:根据用户权限重定向到不同的页面,实现权限控制。
欢迎订阅我的Nextjs 15专栏,入门必备😋