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

Vue Router里的router-link怎么传params参数?

terry 3天前 阅读数 27 #Vue
文章标签 link params

在Vue项目里搞路由跳转时,好多同学碰到router-link传params参数就犯难:参数咋传过去?目标页面咋接收?刷新页面参数咋没了?别慌,这篇文章把router-link传params的事儿从基础到细节掰碎了讲,帮你把这些“坑”都绕过去~

router-link的params是干啥用的?

先搞清楚params是啥,它是Vue Router里“动态路由参数”的载体,用来给不同页面传递资源标识类的数据,举个例子,做电商App的商品详情页,每个商品有唯一ID,路由可以设成/product/:productId,这里的:productId就是动态段,传参时用params把商品ID塞进去,URL就会变成/product/123(假设ID是123),这样做有俩好处:一是URL更“语义化”,用户或搜索引擎一看就知道这页是商品123的详情;二是目标页面能拿到这个ID,去请求对应商品的数据。

再比如做博客系统,文章详情页用/article/:articleId,用户分享链接时,别人点进来能直接定位到对应文章——这就是params让路由“动态”起来的价值。

router-link传params的基本写法是啥样?

传params得配合“命名路由”和“动态路由配置”,步骤分两步:

第一步:配置动态路由

在项目的路由文件(比如router/index.js)里,给对应路由加动态段,举个用户详情页的例子:

const routes = [
  {
    path: '/user/:userId', // 这里的:userId是动态段,用来接收params
    name: 'UserDetail', // 命名路由,传参时要靠它匹配
    component: UserDetail // 目标组件
  }
]

第二步:用router-link传参

在页面里用<router-link>时,得用对象语法,指定nameparams,写法长这样:

<router-link 
  :to="{ 
    name: 'UserDetail', // 对应路由的name
    params: { userId: 123 } // 要传的参数,key和动态段名一致
  }"
>
  去用户详情页
</router-link>

这里要避个坑不能用path代替name传params!比如写成:to="{ path: '/user', params: { userId: 123 }}",Vue Router会直接忽略params——因为path是“死路径”,没法和动态段匹配,只有name能精准对应路由配置里的规则。

目标页面咋接收params参数?

参数传过去了,目标组件得“接住”,常用两种方式,各有优劣,按需选:

直接用$route.params

Vue Router会把参数挂在组件实例的$route对象上,所以在目标组件(比如UserDetail)里,直接读this.$route.params.xxx就行:

export default {
  mounted() {
    console.log(this.$route.params.userId) // 输出传过来的123
  }
}

这种方式简单直接,但有个小问题:组件和路由强耦合,如果之后要改路由参数名,或者把组件复用在其他路由里,得跟着改代码,维护起来有点麻烦。

用props解耦路由和组件

更“优雅”的做法是用props把路由参数传给组件,让组件和路由“解绑”,步骤分两步:

在路由配置里开启props: true

const routes = [
  {
    path: '/user/:userId',
    name: 'UserDetail',
    component: UserDetail,
    props: true // 开启props传参
  }
]

在目标组件里定义props来接收:

export default {
  props: ['userId'], // 这里的key要和路由动态段名一致
  mounted() {
    console.log(this.userId) // 同样能拿到123
  }
}

这样做的好处是:组件不用依赖$route了,之后想在其他地方复用这个组件,或者改路由参数名,只需要在路由配置和传参处调整,组件内部不用动——测试和维护都更方便。

params传参后,页面刷新参数没了咋整?

这是新手最容易踩的“大坑”!比如刚传完params,一刷新页面,参数就没了,原因是:params默认是“内存级”的——如果路由配置里没有对应的动态段,刷新时浏览器重新加载页面,路由信息会被重置,params就丢了。

解决办法分两种场景:

允许参数出现在URL里(推荐)

把参数“钉”在URL的动态段里,也就是路由配置必须有对应的动态段(比如/user/:userId),这样URL会变成/user/123,刷新时Vue Router能从URL里重新解析出params,参数就不会丢,这种方式对SEO和用户分享链接也友好,因为URL里明明白白显示了资源标识。

不想让参数出现在URL里(比如传敏感数据)

如果参数不能暴露在URL(比如用户token),可以用sessionStorage/localStorage暂存,或者用Vuex、Pinia存状态,举个例子,传参前把params存到sessionStorage:

<router-link 
  :to="{ name: 'SecretPage' }"
  @click="saveParams"
>
  去敏感页面
</router-link>
// methods里写
saveParams() {
  sessionStorage.setItem('secretParams', JSON.stringify({ token: 'xxx' }))
}

然后在目标组件的mounted钩子中读取:

export default {
  mounted() {
    const params = JSON.parse(sessionStorage.getItem('secretParams'))
    console.log(params.token) // 拿到暂存的参数
  }
}

但要注意:sessionStorage/localStorage刷新后还在,但关闭标签页会清空;Vuex/Pinia刷新后会丢失,得配合persist插件持久化,所以这种场景要权衡“参数安全性”和“刷新保留”的需求。

router-link传多个params参数咋处理?

实际项目里经常需要传多个参数,比如订单页需要订单ID和tab标识(如详情、物流),做法很简单:

第一步:路由配置多个动态段

const routes = [
  {
    path: '/order/:orderId/:tab', // 多个动态段,用/分隔
    name: 'OrderPage',
    component: OrderPage
  }
]

第二步:router-link传多个params

<router-link 
  :to="{ 
    name: 'OrderPage', 
    params: { orderId: 456, tab: 'detail' } 
  }"
>
  去订单页
</router-link>

第三步:目标组件接收

$route.params的话,直接读this.$route.params.orderIdthis.$route.params.tab;用props的话,路由配置加props: true,组件props里定义两个字段就行:

export default {
  props: ['orderId', 'tab'],
  mounted() {
    console.log(this.orderId, this.tab) // 输出456和detail
  }
}

只要路由配置的动态段和params的key一一对应,传多少个参数都能接住~

params和query传参有啥区别?

很多同学分不清params和query,其实它们适用场景完全不同,对比着看更清楚:

对比维度 params query
URL显示位置 参数在路径里(如/user/123 参数在查询字符串(如/user?name=xxx
刷新后是否保留 路由没配动态段→刷新丢失;配了动态段→刷新保留 刷新后保留(因为在URL里)
使用场景 资源唯一标识(如商品ID、用户ID),让URL语义化 临时筛选/分页参数(如?page=2&search=vue)

举个实际项目的例子:做电商商品列表,商品详情用params/product/123),因为每个商品ID是唯一标识;列表页的搜索关键词用query/product?search=手机),因为搜索是临时筛选,刷新后要保留搜索状态。

传参时遇到的常见错误咋解决?

新手踩坑很正常,把常见错误和解决办法列出来,以后遇到直接“对号入座”:

错误1:传了params,目标页面拿不到

原因大概率是这俩问题:

  • 路由配置没有对应的动态段:比如路由写的是path: '/user',但传了params: { userId: 123 }——没有动态段,params没地方放,自然拿不到。
  • router-link用了path代替name:比如:to="{ path: '/user', params: { userId: 123 }}"——path和params不兼容,Vue Router会忽略params。

解决:路由配置加动态段(如/user/:userId),router-link改用name传参。

错误2:刷新页面后params消失

原因是 params默认“内存级”存储,刷新后路由信息重置,解决办法看前面讲的“场景一”和“场景二”——要么把参数放URL的动态段里,要么用存储工具暂存。

错误3:传对象/数组时,URL显示成[object Object]

因为params本质是“字符串级”的参数,传对象/数组会被强制转成字符串,就会出现乱码,解决办法:

  • 如果参数能暴露在URL,转成JSON字符串传,目标页面再解析:params: { info: JSON.stringify({ name: '张三' }) },目标页面用JSON.parse(this.$route.params.info)
  • 如果参数不能暴露,改用query传(query支持对象,会自动处理成查询字符串),或者用状态管理工具存。
  • (更推荐)尽量别传复杂数据走路由!传个ID之类的标识,目标页面再根据ID请求数据——这样更高效,也避免URL过长。

router-link传params要抓牢这几个关键点:路由配置得有动态段才能让参数“稳”,传参时用name配对params别搞错path,接收的时候用$route或者props都灵活,遇到刷新丢参数就看要不要把参数亮在URL里,把这些逻辑理顺,Vue路由传参就像搭积木一样顺溜~要是你还有其他Vue Router的疑问,评论区喊我,咱随时唠~

版权声明

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

发表评论:

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

热门