Next.js - app 路由器之动态路由与并行路由
#题引:我认为跟着官方文档学习不会走歪路
动态路由的约定
(1) 通过将文件夹名称用方括号括起来可以创建动态段:[folderName]
动态段会作为 params 属性传递给 layout、page、route 和 generateMetadata 函数。
例如,一个博客可以包含以下路由 app/blog/[slug]/page.js,其中 [slug] 是博客文章的动态段。slug是这个动态段的名称,可以被任意有效的 URL 部分替代
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const slug = (await params).slug
return <div>My Post: {slug}</div>
}
由于 params 属性是一个 promise,你必须使用 async/await 或 React 的 use 函数来访问其值。
在版本 14 及更早版本中,params 是一个同步属性。为了向后兼容,在 Next.js 15 中你仍然可以同步访问它,但这个行为将在未来被废弃
(2) 捕获所有段
动态段可以通过在方括号中添加省略号来扩展为捕获所有后续段:[…folderName]
例如,app/shop/[…slug]/page.js 将匹配 /shop/clothes,同时也会匹配 /shop/clothes/tops、/shop/clothes/tops/t-shirts 等。
(3) 可选的捕获所有段
可以通过将参数包含在双方括号中来将捕获所有段设为可选:[[…folderName]]。
例如,app/shop/[[…slug]]/page.js 除了匹配 /shop/clothes、/shop/clothes/tops、/shop/clothes/tops/t-shirts 外,还会匹配 /shop。
捕获所有和可选捕获所有段的区别在于,可选模式下也会匹配不带参数的路由(上例中的 /shop)
并行路由
并行路由允许你在同一个布局中同时或有条件地渲染一个或多个页面。它们对于应用程序中高度动态的部分非常有用,比如仪表板和社交网站上的信息流。
例如,考虑一个仪表板,你可以使用并行路由同时渲染 team 和 analytics 页面:
并行路由是通过命名插槽创建的。插槽使用 @folder 约定来定义。
插槽是用于在布局中定义可插入内容的占位符,可以使用插槽来指定不同的内容区域。这些区域可以根据不同的子路由动态填充。
例如,以下文件结构定义了两个插槽:@analytics 和 @team:
插槽作为 props 传递给共享的父级布局。对于上面的示例,app/layout.js 中的组件现在接收 @analytics 和 @team 插槽 props,并可以与 children prop 一起并行渲染
export default function Layout({
children,
team,
analytics,
}: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
}) {
return (
<>
{children}
{team}
{analytics}
</>
)
}
这个功能使用传统的组件导入也能实现,虽然并行路由在初看上去可能显得复杂,但它实际上为开发者提供了更高的灵活性和可维护性。
传统组件导入:
- 通过手动导入和组合组件来构建页面。
- 可能需要复杂的状态管理和条件渲染逻辑。
- 难以处理多个子路由的嵌套和状态同步。
并行路由:
- 简化了页面结构,使得不同部分的路由可以独立管理。
- 允许不同的子路由同时存在,并且各自的状态和生命周期可以独立处理。
- 更易于维护和扩展,特别是在大型应用中。
插槽分为静态插槽和动态插槽
- 静态插槽:在路由中定义的插槽,其内容在构建时是固定的,不会根据 URL 或其他因素动态变化。
假设您有一个静态插槽 @team,访问 /dashboard/@team 时,会渲染 page.js 或 default.js,内容在构建时已经确定。app/ ├── dashboard/ │ ├── @team/ │ │ ├── page.js │ │ └── default.js
- 动态插槽:在路由中定义的插槽,其内容可以根据 URL 参数或其他动态数据进行变化。
/app
└── dashboard
└── @team
├── default.js
└── [id]
└── page.js
当用户访问特定 URL 时,Next.js 会检查与该 URL 匹配的路由,并确定哪些插槽应该被渲染。如果某个插槽的内容与当前 URL 匹配,它将被标记为活动状态,进行渲染;如果不匹配,则视为不活动。
对于不匹配的插槽,Next.js 需要决定如何处理:如果该插槽有 default.js 文件,Next.js 将渲染该文件的内容。 如果没有 default.js 文件,Next.js 将返回一个 404 页面,表示该内容不存在。
如下面的例子,当用户访问/dashboard/123时,页面会渲染/dashboard/[id]/page.tsx, 并行路由/dashboard/@analytics/[id]/page.tsx ,/dashboard/@team/default.tsx ,因为Next.js没有找到匹配的/dashboard/@team/[id]/page.tsx ,所以渲染的事@team下的default文件,
如果@team连default文件都没有,页面会呈现404。
插槽不是路由段,也不会影响 URL 结构,在同一路由段级别上,你不能同时拥有静态和动态插槽。如果一个插槽是动态的,那么该级别的所有插槽都必须是动态的。
并行路由可以独立流式传输,允许你为每个路由定义独立的错误和加载状态