动态路由
当你不知道确切的路由段名称, 又想用动态数据创建路由时, 你可以使用 Dynamic Segments(动态段), 它会在请求时被填写或在构建时被预渲染.
Convention (文件名协定)
用方括号括起文件夹名称, 即可创建动态段, 如: [文件夹名称]
. 比如, [id]
或 [slug]
.
Dynamic Segments(动态段) 会被作为 params
参数传递给 layout
, page
, route
和 generateMetadata
函数
Example (示例)
比如, 一个 blog 可以包含以下路径 app/blog/[slug]/page.js
, 其中 [slug]
是 blog 文章的 Dynamic Segment(动态段).
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>;
}
Route(路径) | Example URL (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() 页面来学习怎么为段生成参数.
请注意: Dynamic Segments(动态段) 与
pages
目录内的Dynamic Routes(动态路由) 是相同的.
Generating Static Params (生成静态参数)
generateStaticParam
函数可被用来与 dynamic route segments(动态路由段) 相结合, 用来在应用构建时statically generate(静态生成)路由, 而不是在每次请求时动态生成.
export async function generateStaticParams() {
const posts = await fetch("https://.../posts").then((res) => res.json());
return posts.map((post) => ({
slug: post.slug,
}));
}
generateStaticParams
函数最主要的好处是, 它能够自动检索数据. 如果在 generateStaticParams
函数中时使用了 fetch
获取了内容, 那么请求会被 automatically memoized(自动记录). 这意味着, 在多个使用了 generateStaticParams
的 Layouts(布局) 和 Pages(页面) 中使用相同参数的 fetch
请求只会发出一次, 这会缩短构建时间.
如果你正在从 pages
目录迁移, 请参考 migration guide(迁移指南).
查看 generateStaticParams
server function documentation(generateStaticParams 服务端函数文档)获取更多信息和使用案例.
Catch-all Segments (捕获所有的路由段)
通过在括号 [...folderName]
内添加省略号, 可将动态段扩展为捕获所有的路由段.
比如, app/shop/[...slug]/page.js
会匹配 /shop/clothes
, 同样也会匹配 /shop/clothes/tops
, shop/clothes/tops/t-shirts
等.
Route(路径) | Example URL (示例 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']} |