Skip to main content

动态路由

当你事先不知道确切的路段名称并希望从动态数据创建路由时,你可以使用在请求时填充的动态路段或在构建时填充的 prerendered

¥When you don't know the exact segment names ahead of time and want to create routes from dynamic data, you can use Dynamic Segments that are filled in at request time or prerendered at build time.

惯例

¥Convention

可以通过将文件或文件夹名称括在方括号中来创建动态段:[segmentName]。例如,[id][slug]

¥A Dynamic Segment can be created by wrapping a file or folder name in square brackets: [segmentName]. For example, [id] or [slug].

动态段可以从 useRouter 访问。

¥Dynamic Segments can be accessed from useRouter.

示例

¥Example

例如,博客可以包含以下路由 pages/blog/[slug].js,其中 [slug] 是博客帖子的动态分段。

¥For example, a blog could include the following route pages/blog/[slug].js where [slug] is the Dynamic Segment for blog posts.

import { useRouter } from 'next/router'

export default function Page() {
const router = useRouter()
return <p>Post: {router.query.slug}</p>
}
路由示例网址params
pages/blog/[slug].js/blog/a{ slug: 'a' }
pages/blog/[slug].js/blog/b{ slug: 'b' }
pages/blog/[slug].js/blog/c{ slug: 'c' }

捕获所有片段

¥Catch-all Segments

通过在括号 [...segmentName] 内添加省略号,可以扩展动态段以捕获所有后续段。

¥Dynamic Segments can be extended to catch-all subsequent segments by adding an ellipsis inside the brackets [...segmentName].

例如,pages/shop/[...slug].js 将匹配 /shop/clothes,但也会匹配 /shop/clothes/tops/shop/clothes/tops/t-shirts 等。

¥For example, pages/shop/[...slug].js will match /shop/clothes, but also /shop/clothes/tops, /shop/clothes/tops/t-shirts, and so on.

路由示例网址params
pages/shop/[...slug].js/shop/a{ slug: ['a'] }
pages/shop/[...slug].js/shop/a/b{ slug: ['a', 'b'] }
pages/shop/[...slug].js/shop/a/b/c{ slug: ['a', 'b', 'c'] }

可选的包罗万象的段

¥Optional Catch-all Segments

通过将参数包含在双方括号中,可以使包罗万象的段成为可选:[[...segmentName]]

¥Catch-all Segments can be made optional by including the parameter in double square brackets: [[...segmentName]].

例如,除了 /shop/clothes/shop/clothes/tops/shop/clothes/tops/t-shirts 之外,pages/shop/[[...slug]].js 还会匹配 /shop

¥For example, pages/shop/[[...slug]].js will also match /shop, in addition to /shop/clothes, /shop/clothes/tops, /shop/clothes/tops/t-shirts.

catch-all 和可选的 catch-all 段之间的区别在于,使用可选时,不带参数的路由也会被匹配(上例中的 /shop)。

¥The difference between catch-all and optional catch-all segments is that with optional, the route without the parameter is also matched (/shop in the example above).

路由示例网址params
pages/shop/[[...slug]].js/shop{ slug: undefined }
pages/shop/[[...slug]].js/shop/a{ slug: ['a'] }
pages/shop/[[...slug]].js/shop/a/b{ slug: ['a', 'b'] }
pages/shop/[[...slug]].js/shop/a/b/c{ slug: ['a', 'b', 'c'] }