Code前端首页关于Code前端联系我们

一、先搞懂router params是干啥的?

terry 2周前 (10-01) 阅读数 47 #Vue

不少刚学Vue3路由的同学,碰到router params总是犯懵:到底咋传参?页面咋接收?动态路由和params啥关系?刷新后参数没了咋整?今天就把Vue3里router params的用法、坑点、和query的区别这些事儿,掰开了揉碎了讲明白,从基础到进阶一次搞透~

router params是Vue Router里用来在不同页面间传递**“资源标识类数据”**的工具,打个比方,做用户详情页时,每个用户对应唯一ID(比如123),访问路径写成`/user/123`,这里的`123`就是params里的`id`,它的核心作用是**让路由和数据强绑定**——看到路径就知道页面要展示哪个用户、哪件商品的信息。

和URL里的“查询参数(query)”比起来,params更像路径里的“动态片段”,比如筛选商品用/goods?category=book&page=2categorypage是query(属于“可选筛选条件”);而用户ID、订单号这类“没它页面就失去意义”的数据,就得用params+动态路由来传。

给router params传参,两种方式要分清

Vue3里传params主要靠声明式导航(编程式导航(router.push 等),但细节没处理好,传了也白传。

声明式导航:里传params

to的对象语法时,必须配合路由的name(不能用path!),举个实际例子:假设路由配置长这样——

const routes = [
  {
    name: 'User', // 路由的name,传参必须用它
    path: '/user/:id', // 动态段:id,对应params里的id
    component: User
  }
]

页面里用传参得这么写:

<router-link 
  :to="{ 
    name: 'User', // 匹配路由的name
    params: { id: 123 } // 要传的参数
  }"
>去用户123的详情页</router-link>

要是写成path: '/user/:id'再传params,Vue Router会直接忽略params(因为path和params的绑定关系不明确),所以记住:声明式传params,name是关键

编程式导航:router.push里传params

在setup语法糖里,得先用useRouter拿到router实例,再用push方法,代码示例:

<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const goToUser = () => {
  router.push({
    name: 'User', // 同样必须用name
    params: { id: 456 }
  })
}
</script>

和声明式同理,要是写成path: '/user/:id'再传params,params会被直接忽略,路径里的:id也不会被替换,等于白传。

页面接收router params,一行代码搞定

传完参后,目标页面(比如User组件)得把params拿出来用,Vue3里用useRoute钩子,直接取route.params里的参数就行。

代码示例:

<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 假设路由是/user/:id,这里就能拿到id
const userId = route.params.id 
console.log('当前用户ID:', userId) // 比如打印出123
</script>

如果路由配置里有多个动态段(比如path: '/order/:orderId/:tab'),那route.params里就有orderIdtab两个属性,按需取值即可。

动态路由匹配:params生效的前提

很多同学传了params但刷新就没了,或者路径不对,核心原因是路由配置没做“动态路由匹配”

路由配置必须写“动态段”

比如要传用户id,路由得写成path: '/user/:id',这里的:id动态段”,它和params里的id一一对应,要是路由写成path: '/user',然后传params: { id: 123 },虽然能跳转,但params只存在于“内存路由记录”里——一旦刷新页面,params就没了(因为URL里没存这个参数)。

所以规则是:想要params刷新不丢,路由必须配置动态段,让参数“嵌”在URL路径里。

多参数的动态路由

如果有多个参数(比如订单页需要订单id和标签),路由可以这么配:

{
  path: '/order/:orderId/:tab',
  name: 'Order',
  component: Order
}

传参时,params里对应写orderIdtab;接收时,用route.params.orderIdroute.params.tab就能拿到值。

params和query传参,区别大到要注意场景

很多同学分不清params和query,导致场景用错,这里从路径表现、刷新保留、使用场景三个维度对比:

对比项 params(动态路由下) query
路径表现 在URL路径里,如/user/123 在URL后带,如/goods?page=2
刷新后是否保留 保留(因为URL里有) 保留(因为URL里有)
场景适合 资源唯一标识(如用户ID、订单号) 筛选、分页、可选条件(如搜索关键词)

举个场景例子:做电商商品列表,“分类”“页码”适合用query(用户分享链接,别人打开能看到同样的筛选结果);而商品详情页的“商品ID”必须用params+动态路由(每个商品对应唯一路径,如/goods/1001,刷新也得保留ID)。

要是用反了,比如把商品ID放query里,路径变成/goods?productId=1001,虽然功能能实现,但路径不够“语义化”,也不符合RESTful设计(资源路径应该包含标识)。

params传参不生效?这几个坑要避开

传参时遇到“参数传了但接收不到”“刷新后参数没了”,大概率是踩了这些坑:

用path传params(最常见!)

前面强调过,传params时必须用name,不能用path,比如写成这样:

router.push({
  path: '/user/:id', // 错误!path里的:id不会被params替换
  params: { id: 123 }
})

这时候Vue Router会直接忽略params,路径还是/user/:id(没被替换成123),自然接收不到参数。解决方法:把path改成name

路由配置没动态段

如果路由是path: '/user',然后传params: { id: 123 },虽然能跳转,但params只存在于内存中,刷新页面后就没了。解决方法:给路由加动态段,如path: '/user/:id'

参数名和动态段不匹配

路由配置是path: '/user/:userId',但传参时写params: { id: 123 },这时候route.params里没有userId,自然拿不到值。解决方法:传参的key和路由动态段的名字保持一致

进阶:动态路由下的组件更新问题

当用户从/user/1跳转到/user/2时,因为是同一个User组件,Vue不会销毁重建组件,所以组件里的生命周期(如onMounted)不会重新执行,这时候如果依赖params更新数据,就会出问题(比如页面还是用户1的信息)。

用watch监听route.params

在setup里,用watch监听route.params的变化:

<script setup>
import { useRoute, watch } from 'vue-router'
const route = useRoute()
watch(
  () => route.params.id, 
  (newId, oldId) => {
    // newId是新的用户ID,这里发请求重新获取数据
    fetchUserInfo(newId)
  }
)
</script>

用onBeforeRouteUpdate钩子

这是Vue Router提供的导航守卫,在路由更新前触发(同一个组件实例下):

<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
onBeforeRouteUpdate((to, from) => {
  // to是目标路由,to.params.id是新ID
  const newId = to.params.id
  fetchUserInfo(newId)
})
</script>

两种方法选其一就行,目的是在params变化时,强制更新页面数据。

掌握这几步,router params不再难

  1. 传参:声明式用<router-link :to="{name, params}">,编程式用router.push({name, params}),必须用name
  2. 接收:用useRoute().params.xxx拿参数;
  3. 路由配置:要传的参数必须在path里写动态段(如:id),否则刷新丢参数;
  4. 场景区分:资源标识用params+动态路由,筛选条件用query
  5. 踩坑点:别用path传params、参数名和动态段要一致、动态路由下要处理组件更新。

把这些逻辑理顺,不管是做用户系统、订单系统还是商品详情页,用router params传参都能游刃有余~要是还有细节没搞懂,评论区随时问,咱们再唠~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门