Dynamic Segments
当你不知道精确的 segment 名并且想要从动态的数据创建时,你可以使用在请求时填充或者在构建时提前获取的Dynamic Segments(动态路由片段)。
约定
动态路由片段通过中括号包裹的方式创建:[folderName]。例如[id]或者[slug]。
动态路由片段会被当做 paramsprop 传递给layout、page、route以及generateMetadata函数。
例子
举例来说,一个 blog 能够包含这样的路由app/blog/[slug]/page.js。[slug]就是动态的分段路径。
tsx1export default function Page({ params }: { params: { slug: string } }) { 2 return <div>My Post: {params.slug}</div> 3}
| 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' } |
跟 page 路由的 getStaticPath 类似,我们需要配合generateStaticParams来生成数组结构的数据。
Generating Static Params
generateStaticParams函数可以与动态路由段结合使用,以在构建时静态生成路由,而不是在请求时按需生成。
js1export async function generateStaticParams() { 2 const posts = await fetch('https://.../posts').then((res) => res.json()) 3 4 return posts.map((post) => ({ 5 slug: post.slug, 6 })) 7}
generateStaticParams 函数的主要优点是其智能数据检索。如果在 generateStaticParams 函数内部使用 fetch 请求获取内容,则这些请求会自动去重。这意味着在多个 generateStaticParams、Layout 和 Page 中具有相同参数的 fetch 请求只会执行一次,从而减少构建时间。
generateStaticParams会在构建时运行(不是请求时运行)。
Catch-all Segments
Danamic-Segments 能够被展开以用于获取所有的路径分段,使用语法[...folderName]。
举个例子,app/shop/[...slug]/page.js可以捕获到/shop/clothes,或者/shop/clothes/tops等更多路径分段。
| 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'] } |
可选的 Catch-all Segments
可以通过在双方括号来将Catch-all Segments设置为可选:[[...folderName]]。
例如,app/shop/[[...slug]]/page.js将匹配/shop,以及/shop/clothes、/shop/clothes/tops、/shop/clothes/tops/t-shirts。
Catch-all Segments和可选Catch-all Segments之间的区别在于,可选的情况下,没有参数的路由也会被匹配(例如上面例子中的/shop)
| Route | Example URL | params |
|---|---|---|
app/shop/[[...slug]]/page.js | /shop | {} |
app/shop/[[...slug]]/page.js | /shop/a | { slug: ['a'] } |
TypeScript 支持
当使用TypeScript时,我们需要根据配置好的分段路由来定义类型:
js1export default function Page({ params }: { params: { slug: string } }) { 2 return <h1>My Page</h1> 3}
| 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 } |