Next.js平行路由
外观
Next.js平行路由[编辑 | 编辑源代码]
平行路由(Parallel Routes)是Next.js 13+引入的高级路由模式,允许在同一布局中同时或条件性渲染多个独立的路由段。这种模式打破了传统线性路由的层级限制,特别适合构建复杂界面如仪表盘、多视图应用等场景。
核心概念[编辑 | 编辑源代码]
平行路由的核心特征包括:
- 独立加载:每个路由段拥有独立的加载状态和错误边界
- 共享URL:所有平行路由段共享相同的URL路径
- 动态组合:可通过条件逻辑控制不同路由段的显示
与传统嵌套路由对比[编辑 | 编辑源代码]
实现机制[编辑 | 编辑源代码]
平行路由通过特殊的命名插槽实现。在Next.js文件系统中,使用@folder
约定定义平行路由段:
app/ ├── @sidebar/ │ └── page.tsx ├── @content/ │ └── page.tsx └── layout.tsx
基础示例[编辑 | 编辑源代码]
以下是一个仪表盘布局的平行路由实现:
// app/dashboard/layout.tsx
export default function Layout({
children,
sidebar,
content
}: {
children: React.ReactNode
sidebar: React.ReactNode
content: React.ReactNode
}) {
return (
<div className="dashboard">
<nav className="sidebar">{sidebar}</nav>
<main className="content">{content}</main>
<aside className="widgets">{children}</aside>
</div>
)
}
高级用法[编辑 | 编辑源代码]
条件渲染[编辑 | 编辑源代码]
平行路由可以与React的条件渲染结合:
// app/dashboard/layout.tsx
export default function Layout({
sidebar,
content
}: {
sidebar: React.ReactNode
content: React.ReactNode
}) {
const [viewMode] = useViewMode() // 'full' | 'compact'
return (
<>
{viewMode === 'full' && sidebar}
{content}
</>
)
}
动态插槽[编辑 | 编辑源代码]
通过插槽名称的动态计算实现更灵活的配置:
// app/[tab]/layout.tsx
export default function Layout({
params,
analytics,
settings
}: {
params: { tab: string }
analytics: React.ReactNode
settings: React.ReactNode
}) {
const CurrentTab = params.tab === 'analytics' ? analytics : settings
return <div>{CurrentTab}</div>
}
实际案例[编辑 | 编辑源代码]
案例1:可折叠侧边栏[编辑 | 编辑源代码]
实现一个保留状态的可折叠侧边栏:
对应代码实现:
// app/layout.tsx
'use client'
export default function Layout({
sidebar,
content
}: {
sidebar: React.ReactNode
content: React.ReactNode
}) {
const [isExpanded, setIsExpanded] = useState(true)
return (
<div className={`container ${isExpanded ? 'expanded' : 'collapsed'}`}>
<div className="sidebar-wrapper">
<button onClick={() => setIsExpanded(!isExpanded)}>
{isExpanded ? '◀' : '▶'}
</button>
{isExpanded && sidebar}
</div>
{content}
</div>
)
}
案例2:多步骤表单[编辑 | 编辑源代码]
使用平行路由实现表单步骤的持久化状态:
app/ ├── @step1/ │ └── page.tsx ├── @step2/ │ └── page.tsx ├── @step3/ │ └── page.tsx └── layout.tsx
// app/layout.tsx
export default function FormWizard({
step1,
step2,
step3,
params
}: {
step1: React.ReactNode
step2: React.ReactNode
step3: React.ReactNode
params: { step: string }
}) {
return (
<form>
{params.step === '1' && step1}
{params.step === '2' && step2}
{params.step === '3' && step3}
</form>
)
}
性能考量[编辑 | 编辑源代码]
平行路由通过路由段隔离带来多项性能优势:
- 更细粒度的加载:每个路由段有独立的
loading.tsx
- 局部更新:仅重新渲染变更的路由段
- 预加载控制:可通过
prefetch
单独控制
数学表达并行加载效益:
其中表示第n个路由段的加载时间。
常见问题[编辑 | 编辑源代码]
页面模块:Message box/ambox.css没有内容。
平行路由仍在演进中,需注意以下限制: |
- TypeScript类型:需要手动定义插槽props类型
- 默认路由:未匹配时会渲染
default.js
或空白 - 服务器组件:平行路由段默认是服务器组件
最佳实践[编辑 | 编辑源代码]
1. 命名一致性:保持插槽名称与目录名一致
2. 错误隔离:为每个路由段添加error.tsx
3. 加载状态:设计有意义的加载指示器
4. URL设计:合理规划路由参数
进阶阅读[编辑 | 编辑源代码]
- Next.js官方文档:Parallel Routes RFC
- React模式:Composition vs Inheritance
- 前端架构:Micro Frontends设计模式