Vue Router里的router-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>
时,得用对象语法,指定name
和params
,写法长这样:
<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.orderId
和this.$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前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。