Next.js - 动态路由

规则


用方括号封装文件夹名称,即可创建动态段: [文件夹名称]。例如,[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>
}
RouteExample URLparams
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 等。

RouteExample URLparams
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)。

RouteExample URLparams
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>
}
Routeparams 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 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值