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

Vue Router里query和params有啥区别?一篇文章讲明白

terry 6小时前 阅读数 9 #Vue

Vue Router作为Vue项目里管理页面跳转和路由逻辑的核心工具,传参时“query”和“params”是最常用的两种方式,但很多刚上手的同学经常搞混它们的区别,比如为啥有时候刷新页面参数就没了?为啥传参时用path会失效?今天咱就从定义、写法、URL表现、刷新影响这些角度,把query和params的区别掰碎了讲清楚,再聊聊实际开发该咋选~

定义与本质:query是“查询串”,params是“路径段”

先理解两者的本质:

query 更像“附加在URL后的查询参数”,和网页里常见的 ?keyword=xxx&sort=xxx 是一个逻辑——多个参数用 & 连接,属于URL的一部分,但和路由路径是“分离”的关系。

params 则是“路由路径里的动态片段”,比如路由配置写了 path: '/user/:id',这里的 :id 就是给params预留的“占位符”,实际跳转时传入的参数会直接替换这个位置,成为路径的一部分(/user/123 里的 123 就是params)。

举个生活例子:假设你要找一家叫“XX书店”的店铺,query像“书店里的搜索框”(搜书名、作者),params像“书店所在的街道门牌号”(确定你要去哪家分店)。

传参时的写法:path/name搭配有讲究

在Vue里,路由跳转靠 this.$router.push(),传query和params的写法差异很大,关键看和 path 还是 name 搭配:

query传参:path/name都能“搭”

query不挑 pathname,两种方式都能传参,比如做一个文章列表页,传“分类”和“页码”:

// 方式1:用path传query
this.$router.push({
  path: '/article-list',
  query: { category: '前端', page: 2 }
})
// 方式2:用name传query(路由配置里name叫ArticleList)
this.$router.push({
  name: 'ArticleList',
  query: { category: '前端', page: 2 }
})

两种写法最终的URL都是 /article-list?category=前端&page=2,目标页面用 this.$route.query.category 就能拿到参数。

params传参:必须和name“绑定”

params传参只能用name,因为 path 是“静态路径”,除非路由配置了动态段,否则 path 无法识别params,正确写法得这样:

先看路由配置(必须给params留位置):

{
  name: 'ArticleDetail', // 路由记录的名称
  path: '/article/:id', // 动态段:id是给params用的
  component: ArticleDetail
}

然后跳转时用name传params:

this.$router.push({
  name: 'ArticleDetail',
  params: { id: '123456' } // 这里的id对应路由里的:id
})

此时URL会变成 /article/123456,目标页面用 this.$route.params.id 就能拿到文章ID。

如果错误地用path传params

this.$router.push({
  path: '/article/:id', // 这种写法无效!path里不能直接写参数
  params: { id: '123456' }
})

URL还是 /article/:id,params也传不过去——因为 path 是静态解析的,不认params,传了也白传。

URL呈现形式:一个“外显”,一个“内隐”

从URL上看,query和params的显示逻辑完全不同

query:明明白白“写在URL后”

query参数会直接暴露在URL的 后面,/search?keyword=Vue&type=视频,不管页面怎么刷新、分享链接,别人点开能直接看到这些参数。

params:要么“嵌在路径”,要么“藏在内存”

params的显示分两种情况:

  • 路由配置了动态段path: '/user/:uid'):此时params的 uid 会替换到路径里,URL变成 /user/1001,参数“外显”在路径中;

  • 路由没配置动态段path: '/user'):此时用name传params,URL还是 /user,但params会存在“内存里的路由记录”中(目标页面能通过 this.$route.params 拿到),但!刷新页面后,这部分参数就没了——因为URL里没存这些信息,浏览器刷新时不会保留内存里的临时数据。

页面刷新后,参数还“存活”吗?

这是很多同学踩坑的点,直接影响功能稳定性,咱分情况看:

query参数:刷新“稳如老狗”

因为query参数明明白白写在URL里,浏览器刷新时会保留URL的查询串,所以目标页面用 this.$route.query 拿到的参数刷新后还在

比如搜索页 /search?keyword=Vue,刷新后还是这个URL,this.$route.query.keyword 依然能拿到 Vue

params参数:“存活”看路由配置

params是否能在刷新后保留,取决于路由有没有配置动态段

  • 配置了动态段(如 path: '/user/:uid'):此时params的 uid 会被解析到URL里(如 /user/1001),刷新后URL还在,this.$route.params.uid 也能拿到;

  • 没配置动态段(如 path: '/user'):params只存在于内存的路由记录中,刷新页面后,前端路由重新初始化,这部分参数就“丢了”,this.$route.params 会变成空对象。

举个实际坑点:做用户个人中心时,若路由没配 /user/:uid,只配了 /user,然后用name传 params: { uid: 1001 },刷新后个人中心页面就拿不到 uid 了,导致数据加载失败,所以这种场景下,一定要给params配动态段,让参数“外显”在URL,才能保证刷新不丢。

对路由配置的要求:query“零配置”,params“需声明”

路由配置层面,query和params的要求天差地别:

  • query参数:完全不需要在路由配置里做任何处理,不管路由是 path: '/home' 还是 path: '/about',只要跳转时传query,目标页面用 this.$route.query 就能拿到参数;

  • params参数:如果想让参数“持久化”(刷新不丢),必须在路由的 path声明动态段path: '/product/:pid'),如果不声明,params只能作为“临时参数”存在,刷新就丢。

实际开发咋选?看场景需求

理解区别后,关键是根据业务场景选对方式,不然容易踩坑,咱分场景说:

适合用query的场景

  • 列表页的筛选/排序/分页:比如电商商品列表的“分类、价格区间、页码”,这些参数需要在URL中保留,方便用户刷新、分享、回退时看到相同结果,像 /goods?category=手机&price=1000-3000&page=3,用query完美匹配;

  • 搜索页面的关键词:搜索结果页必须把关键词存在URL,用户刷新后还能看到之前搜的内容(如 /search?keyword=Vue教程);

  • 多tab切换的状态:后台管理系统的标签页,不同tab的状态用query存,切换标签时URL变化,刷新后tab状态不丢。

适合用params的场景

  • 页面级的唯一标识:用户详情页的用户ID、文章详情页的文章ID,这些属于页面的核心参数,用params配合路由动态段,让URL更语义化。/user/1001/user?id=1001 更简洁直观;

  • 不需要暴露的临时参数(慎选):如果有临时参数不想在URL显示,且页面不刷新(比如单页应用内的跳转),可以用params传,但这种情况很少,因为刷新就丢,所以更推荐“需要持久化的params”一定要配动态段。

举个综合例子:做博客系统时,文章列表页用query传“分类、页码”(/articles?category=前端&page=2),用户分享链接后别人能直接看到对应内容;文章详情页用params传“文章ID”(路由配 /articles/:aid,跳转后URL是 /articles/123),既语义化又能保证刷新后文章ID还在。

常见错误与避坑指南

最后聊聊开发中容易犯的错,提前避坑:

  1. 用path传params,参数丢失
    记住params必须和 name 绑定,path 不认params,跳转时要传params,就用 name,别碰 path

  2. 刷新后params丢失,页面崩了
    先检查路由配置有没有动态段,比如传 userID,路由里得有 path: '/user/:uid',而不是 path: '/user',配好动态段,params才能“外显”在URL,刷新不丢。

  3. 混淆$router和$route
    传参时用 this.$router.push()(操作路由跳转),接收参数时用 this.$route.querythis.$route.params(当前路由的信息),别写成 this.$router.query,这是错的——$router 是“操作路由的工具”,$route 才是“当前路由的信息包”。

记住这几个核心区别

最后帮你提炼关键对比,下次遇到传参需求直接对应场景选:

对比维度 query参数 params参数
定义 URL后的查询串(?key=value) 路由路径里的动态片段(如/user/:id)
传参写法 path/name都能传 必须用name,且路由要配动态段
URL显示 外显在?后(如?a=1&b=2) 要么嵌在路径(配动态段时),要么隐式存在(没配时,刷新丢)
刷新后留存 保留(因为在URL里) 配动态段则保留,没配则丢失
路由配置要求 零配置 需配动态段才能持久化
适用场景 需保留、分享的参数(筛选、搜索等) 页面核心标识、语义化URL(用户ID、文章ID等)

现在再遇到Vue Router传参,心里就有数啦~选query还是params,对照场景和区别,再也不踩坑~

版权声明

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

发表评论:

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

热门