03 / 09

动态路由为什么这样设计?

从实际 URL 推导动态参数、嵌套路由和 catch-all 路由的设计。

动态路由为什么这样设计?

学习目标

理解 Nuxt 动态路由的设计思想,而不是死记语法。

学完本章,你应该能够:

  • 理解 [id] 的含义
  • 理解多层动态路由为什么返回对象
  • 理解 [...slug] 为什么返回数组
  • 看到文件名,就知道 params 长什么样

一、这个知识解决什么问题?

上一章我们已经知道 pages/about.vue/about。那如果页面不是固定的呢?

商品详情 /product/1001、用户详情 /user/888……难道要创建无数个文件?显然不现实。

于是,动态路由出现了。


二、我们的讨论过程

第一层:普通动态参数

创建 pages/product/[id].vue,访问 /product/1001/product/9527 都成功。

[id]占位符(Placeholder),Nuxt 会把 1001 保存到 route.params.id

route.params  // → { id: "1001" }

第二层:多参数

pages/[category]/[id].vue,访问 /frontend/1001

这是讨论最久的问题——为什么 route.params 不是嵌套对象?

因为 Nuxt 把每一个 [] 都看成一个参数,最终组成扁平的参数集合:

{ category: "frontend", id: "1001" }

params 是参数集合(Parameter Map),不是树。

第三层:Catch All

pages/[...slug].vue 访问 /docs/nuxt/router/install

route.params  // → { slug: ["docs", "nuxt", "router", "install"] }

为什么是数组?因为不知道到底有几层,Nuxt 只能全部收集起来。


三、最终结论

Nuxt 的动态路由只有三种:

文件名 访问 URL params 结果
[id].vue /1001 { id: "1001" }
[category]/[id].vue /frontend/1001 { category: "frontend", id: "1001" }
[...slug].vue /a/b/c { slug: ["a", "b", "c"] }

四、脑图

Nuxt 动态路由脑图:从文件模板和 URL 推导 route.params

推导顺序:

  1. 把文件路径和实际 URL 逐段对齐
  2. 普通文字是固定路径,不进入 params
  3. 每个 [name] 取出对应的一段,成为 params.name
  4. [...name] 收集剩余所有段,得到数组

注意:URL 参数默认都是字符串,多个 [] 组成扁平参数对象,不会因目录嵌套产生嵌套对象。


五、容易踩坑

[category]/[id] 会形成嵌套对象

不会,永远都是扁平的 { category, id }

[...slug] 是字符串

不是,永远是数组。

[id] 是 Number

不是,URL 参数全部都是 String,需要自己转换:Number(route.params.id)


一句话记忆

一个 [] 对应一个参数;... 表示收集剩余所有路径,因此返回数组。