Vue Router里query和params有啥区别?咋用更顺手?
做Vue项目开发时,路由传参是绕不开的高频操作,Vue Router里的query和params都能传数据,但刚接触的同学常犯懵:这俩到底咋选?传参方式、URL显示、刷新后参数还在不在…这些区别得掰明白才行,今天咱从传参逻辑、显示效果、实际场景这些角度,把query和params的门道聊透,下次开发不纠结~
query和params,传参逻辑有啥不同?
先从「怎么把参数送过去」说起,Vue Router传参分两种思路:query把参数塞到URL的“查询字符串”(后面那串),params把参数藏到路由路径的“动态片段”里(user/:id里的:id)。
举个🌰 做搜索页面,要传关键词和页码,用query的话路由配置很简单:
{ path: '/search', name: 'SearchPage', component: SearchPage }
跳转时不管用<router-link>
还是编程式导航,把参数丢给query
:
<!-- 声明式导航 --> <router-link :to="{ name: 'SearchPage', query: { keyword: '前端', page: 2 }}">去搜索页</router-link> <!-- 编程式导航 --> this.$router.push({ name: 'SearchPage', query: { keyword: '前端', page: 2 } })
这时候URL会变成 /search?keyword=前端&page=2
,参数明明白白挂在URL后。
再看params的传参逻辑,比如做用户详情页,每个用户对应唯一ID,适合把ID嵌到路径里,得先在路由配置里定义动态参数段(就是带:的部分):
{ path: '/user/:id', // :id是动态参数段 name: 'UserDetail', component: UserDetail }
跳转时把用户ID丢给params
:
<!-- 声明式导航 --> <router-link :to="{ name: 'UserDetail', params: { id: 1001 }}">用户1001详情</router-link> <!-- 编程式导航 --> this.$router.push({ name: 'UserDetail', params: { id: 1001 } })
这时候URL变成 /user/1001
,用户ID直接嵌在路径里,看不到?和&。
⚠️ 注意:params传参不一定都要配动态路由,比如路由是path: '/user'
(没配动态段),也能传params,但这种情况参数不会出现在URL里(后面讲刷新时重点说)。
URL显示差异:query明牌,params看配置
从例子能看出,query传的参数一定会暴露在URL的查询字符串里,格式是?key1=value1&key2=value2
,好处是别人复制链接时参数能一起带走,坏处是传敏感信息(比如密码)就不安全了。
params的显示则「看路由配没配动态段」:
- 配了动态段(如
/user/:id
):params里的对应参数会替换路径里的动态段,直接显示在URL中(如/user/1001
)。 - 没配动态段(如
path: '/user'
):params传的参数不会出现在URL里,URL还是/user
,但参数会存在路由实例里(后面讲刷新坑)。
举个反面🌰 假设路由是path: '/user'
,用params传参:
this.$router.push({ name: 'User', params: { nickname: '小明', age: 20 } })
URL还是/user
,但this.$route.params
能拿到{ nickname: '小明', age: 20 }
,但页面一刷新,参数就没了!
刷新页面后,query和params谁能留住参数?
这是很多人踩坑的点!直接给结论:
- query传的参数,刷新后还在:因为参数存在URL的查询字符串里,属于URL的一部分,页面刷新时,浏览器重新请求URL,Vue Router能从URL里重新解析出query参数。
- params传的参数,是否保留看路由配置:
- 配了动态段(如
/user/:id
):params里的参数会被编码到URL路径中,刷新后URL还在,参数能保留。 - 没配动态段:params参数存在内存里(没进URL),页面刷新后内存清空,参数直接丢。
- 配了动态段(如
拿实际场景验证:
- 搜索页用query传参
/search?keyword=前端&page=2
,用户按F5刷新,this.$route.query
里依然能拿到keyword和page,搜索结果还能停在第2页,体验友好。 - 用户详情页路由是
/user/:id
,传参后URL是/user/1001
,刷新后URL还是/user/1001
,Vue Router能从URL解析出id,this.$route.params.id
还在,页面能正常加载用户信息。 - 但如果用户详情页路由是
/user
(没配动态段),用params传参,URL还是/user
,刷新后params里的参数直接没了,页面可能报错或空白——这就是典型的「刷新丢参」坑!
路由配置:query自由,params受限
传参时,query对路由配置几乎「零依赖」——不管路由path咋写,只要用query传参,参数都会塞到查询字符串里,就算路由是最基础的path: '/xxx'
,也不影响query传参。
但params传参想让参数稳定(刷新不丢),必须提前在路由path里配「动态参数段」(比如/user/:id/:name
),如果没配,params传的参数要么不显示在URL(刷新丢参),要么根本传不过去(用path跳转还容易出错)。
⚠️ 插个知识点:用params传参时,建议用命名路由(name)跳转,别用path,因为用path跳转时,Vue Router不会解析params里的参数,得手动拼到path里,麻烦又容易错。
// 不推荐:用path跳转+params,参数不会被解析 this.$router.push({ path: '/user', params: { id: 1001 } }) // URL还是/user,params也传不过去(除非路由配了动态段,但这里没配) // 推荐:用命名路由+params this.$router.push({ name: 'UserDetail', params: { id: 1001 } }) // 前提:路由配置了name: 'UserDetail' 和 path: '/user/:id'
query传参灵活,不用改路由;params传参若想稳定,必须配动态段,且跳转用命名路由更稳。
实际开发选query还是params?看场景!
知道区别后,结合场景选更高效,分两种典型场景唠:
场景1:参数“可选”或“需要分享” → 选query
比如搜索页的关键词、分页页码、电商的筛选条件(价格区间、商品分类):这些参数属于「可选」——用户不选关键词也能进搜索页(只是展示全部结果);而且用户可能想分享带筛选条件的链接,这时候用query最适合,因为参数在URL里,分享后别人点链接能看到一样的结果。
再比如列表页的排序方式(按时间/热度),用query传参,刷新后排序方式还在,体验友好。
场景2:参数是“路由核心标识”或“必须存在” → 选params(配动态路由)
如果页面的存在完全依赖某个参数(比如用户详情页必须有用户ID才能加载数据、商品详情页必须有商品ID),用params+动态路由更合适,因为参数嵌在URL路径里,既保证页面唯一性(每个ID对应唯一页面),又能让SEO更友好(搜索引擎能索引不同ID的页面),而且刷新后参数不会丢。
再比如后台管理系统的「编辑用户」页面,必须传用户ID才能加载要编辑的信息,这时候用/user/edit/:id
这种动态路由+params传参,安全又稳定。
避坑提醒:params别瞎用(非动态路由场景)
前面说过,路由没配动态段时,用params传参虽然跳转后能拿到参数,但刷新就丢,这种场景除非你确定页面不会刷新(比如单页应用里的弹窗页,用户不可能手动刷新),否则千万别这么干!不然用户一刷新,参数没了,页面直接崩掉,体验巨差。
接收参数:都从$route里拿!
最后补个小知识:不管query还是params传的参数,接收时都要从this.$route
里拿(不是this.$router
!$router是路由实例,负责跳转;$route是当前路由信息对象,存着参数、路径这些)。
举个例子,在组件里接收参数:
export default { created() { // 接收query参数 const { keyword, page } = this.$route.query // 接收params参数 const { id } = this.$route.params // 用参数发请求、渲染页面~ } }
⚠️ 注意:如果用params传参但没配动态路由,this.$route.params
里的参数在刷新后会变成空对象,接收时最好做判空处理,避免报错。
:query和params的核心区别在传参方式、URL显示、刷新影响和路由配置依赖上,选的时候记住:需要参数可分享、刷新保留、可选→用query;需要参数是页面核心标识、SEO友好、必须存在→用params(配动态路由),把这俩区别吃透,路由传参就再也不踩坑啦~要是还有疑问,评论区随时唠~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。