规则
用方括号封装文件夹名称,即可创建动态段: [文件夹名称]。例如,[id] 或 [slug]。
动态段可作为参数道具传递给 layout、page、route 和 generateMetadata 函数。
例子
如博客可以包含以下路由 app/blog/[slug]/page.js,其中 [slug] 是博客文章的动态分段。
// app/blog/[slug]/page.tsx
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>
}
Route | Example URL | params |
---|---|---|
app/blog/[slug]/page.js | /blog/a | { slug: 'a' } |
app/blog/[slug]/page.js | /blog/b | { slug: 'b' } |
app/blog/[slug]/page.js | /blog/c | { slug: 'c' } |
可参考 generateStaticParams() 页面了解如何为片段生成参数。
生成静态参数
generateStaticParams 函数可与动态路由段结合使用,以便在构建时静态生成路由,而不是在请求时按需生成。
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
generateStaticParams 函数的主要优点是能智能检索数据。如果使用获取请求在 generateStaticParams 函数中获取内容,则会自动对请求进行备忘。这意味着在多个 generateStaticParams、Layouts 和 Pages 中使用相同参数的获取请求只会发出一次,从而缩短了构建时间。
Catch-all Segments (捕获所有分段)
通过在括号[...文件夹名]内添加省略号,可将动态片段扩展为涵盖所有后续片段。
例如,app/shop/[...slug]/page.js 将匹配 /shop/clothes,但也会匹配 /shop/clothes/tops、/shop/clothes/tops/t-shirts 等。
Route | Example URL | params |
---|---|---|
app/shop/[...slug]/page.js | /shop/a | { slug: ['a'] } |
app/shop/[...slug]/page.js | /shop/a/b | { slug: ['a', 'b'] } |
app/shop/[...slug]/page.js | /shop/a/b/c | { slug: ['a', 'b', 'c'] } |
Optional Catch-all Segments (可选捕获所有分段)
Catch-all Segments可以通过将参数包含在双方括号中而变得可选:[[…folderName]]。
例如,app/shop/[[…slug]]/page.js也将匹配/shop,此外还有/shop/衣服、/shop/服装/上衣、/shop/服装/上衣/t恤。
catch-all和optional-catch-all-segments之间的区别在于,对于optional,不带参数的路线也会匹配(上例中的/shop)。
Route | Example URL | params |
---|---|---|
app/shop/[[...slug]]/page.js | /shop | {} |
app/shop/[[...slug]]/page.js | /shop/a | { slug: ['a'] } |
app/shop/[[...slug]]/page.js | /shop/a/b | { slug: ['a', 'b'] } |
app/shop/[[...slug]]/page.js | /shop/a/b/c | { slug: ['a', 'b', 'c'] } |
TypeScript
使用 TypeScript 时,可以根据配置的路由段为参数添加类型。
// app/blog/[slug]/page.tsx
export default function Page({ params }: { params: { slug: string } }) {
return <h1>My Page</h1>
}
Route | params Type Definition |
---|---|
app/blog/[slug]/page.js | { slug: string } |
app/shop/[...slug]/page.js | { slug: string[] } |
app/[categoryId]/[itemId]/page.js | { categoryId: string, itemId: string } |