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

Vue2 router query 怎么用?常见问题全解答

terry 2天前 阅读数 18 #Vue
文章标签 Vue2 router;query

很多做前端开发的小伙伴,在学Vue2路由的时候,对query参数这块经常犯迷糊——怎么传参?怎么接收?刷新后数据还在吗?和params有啥区别?今天就把Vue2 router query的常见问题掰碎了讲清楚,从基础用法到实战场景,帮你彻底搞懂~

Vue2里router query是干啥的?

先理解路由参数的两种形式:路径参数(params)查询参数(query),query就像浏览器地址栏里后面跟着的键值对,比如百度搜索“前端学习”后,url里的wd=前端学习就是查询参数。

在Vue2路由中,query的核心作用是在不同页面间传递“不需要隐藏”的参数,这些参数会明明白白显示在url上,而且页面刷新后不会丢失(因为url本身带着这些信息)。

举个和params的直观对比例子:假设做一个用户页面,路径是/user

  • 用params传参:得把路由配置成/user/:id(变成动态路由),此时url是/user/123
  • 用query传参:路由配置不用改,url是/user?id=123

简单说,query是“附加”在url后面的参数,不影响路径结构;params是“嵌入”到路径里的参数,需要路由提前规划好动态段。

怎么用router-link传query参数?

大部分时候,我们用<router-link>组件实现声明式导航,传query参数得用“对象语法”的to属性。

实际例子:从首页跳商品列表页传参

假设要从首页跳转到商品列表页,同时传“分类ID”和“排序方式”两个参数,代码可以这么写:

<router-link 
  :to="{ 
    path: '/product-list', 
    query: { 
      categoryId: 3, 
      sort: 'price-desc' 
    } 
  }"
>查看数码产品</router-link>

点击后,url会变成/product-list?categoryId=3&sort=price-desc,这里要注意3个点:

  1. 必须用:to(v-bind:to)绑定对象——因为要传动态的query参数;
  2. 别用字符串语法硬拼url(比如to="/product-list?categoryId=3")——遇到中文、特殊符号容易编码错误,对象语法更稳妥;
  3. 路由配置不用改——不管/product-list的路由规则咋写,query参数都会被追加到url上。

编程式导航怎么传query参数?

如果是按钮点击、异步请求后跳转这类“命令式”场景,得用this.$router.push()方法。

实际例子:点击“立即购买”跳订单页传参

用户点击“立即购买”按钮后,跳转到订单页并传商品ID和购买数量:

methods: {
  goToOrder() {
    this.$router.push({
      path: '/order',
      query: { 
        productId: this.product.id,
        count: this.buyCount 
      }
    })
  }
}

跳转后url是/order?productId=1001&count=2,这里也可以用路由的name来导航(更推荐,尤其是路由配置了name时):

// 假设路由配置:{ name: 'orderPage', path: '/order' }
this.$router.push({
  name: 'orderPage',
  query: { 
    productId: this.product.id,
    count: this.buyCount 
  }
})

两种方式(path或name)都能传query,区别是name是路由的“别名”,更灵活(比如以后路径改了,只要name不变,代码不用改),但要注意:不管用path还是name,query都会被正常追加到url上

页面里怎么接收query参数?

到了目标页面(比如Order组件),要获取传过来的productIdcount,得用this.$route.query

实际例子:在Order组件里取参数

在组件的生命周期钩子(比如mounted)或者方法里取参数:

export default {
  mounted() {
    const { productId, count } = this.$route.query;
    console.log('商品ID:', productId); // 输出类似 "1001"
    console.log('购买数量:', count); // 输出类似 "2"
  }
}

这里一定要分清$router$route

  • $router是VueRouter的实例,用来做“跳转操作”(push、replace、go等);
  • $route是当前活跃的路由信息对象,里面存着path、query、params、meta等数据,用来“读参数”。

要是写错成this.$router.query,控制台会报错“undefined”,因为$router根本没有query这个属性~

query参数刷新后还在吗?

很多同学担心页面刷新后参数丢了,这里明确说:query参数因为是拼在url上的,所以刷新后还在

原理&测试场景

浏览器刷新页面时,会把当前url发给服务器,服务器返回页面后,Vue Router会解析url里的query参数,所以this.$route.query还能拿到之前的值。

举个测试场景:在商品列表页用query传了categoryId=3,跳转到列表页后刷新浏览器,url还是/product-list?categoryId=3,mounted里打印this.$route.query.categoryId,依然能拿到3。

但如果是用params传参(且路由没配置动态段),刷新后就会丢失——因为params没被放到url里,属于“内存级”参数,这也是query和params的核心差异之一。

怎么清除query参数?

有时候跳转后想把之前的query参数清空,比如从商品详情页回到列表页,不需要保留之前的筛选条件,这时候可以在跳转时给query传空对象。

实际例子:从详情页跳回列表页清空参数

从详情页跳回列表页时,清空所有query参数:

this.$router.push({
  path: '/product-list',
  query: {} // 清空所有query参数
})

这样url就会变成/product-list(没有后面的内容),如果只想清除部分参数,比如保留categoryId但清除sort,可以传{ categoryId: this.$route.query.categoryId, sort: '' },不过更推荐传需要保留的参数,避免遗漏。

query参数的类型有限制吗?

有同学尝试传对象、数组,发现url里变成了[object Object]或者逗号分隔的字符串,这是因为url只能存储字符串类型的参数,Vue Router会自动把非字符串参数转成字符串(比如数字转字符串没问题,但对象会被转成[object Object])。

问题复现&解决方法

比如传这样的query:

this.$router.push({
  path: '/test',
  query: { 
    info: { name: '小明', age: 18 },
    hobbies: ['篮球', '游戏'] 
  }
})

url会变成/test?info=[object%20Object]&hobbies=篮球,游戏,接收的时候info是字符串"[object Object]"hobbies是字符串"篮球,游戏",根本没法用。

解决方法:把复杂数据转成JSON字符串

// 传参时
const infoStr = JSON.stringify({ name: '小明', age: 18 });
const hobbiesStr = JSON.stringify(['篮球', '游戏']);
this.$router.push({
  path: '/test',
  query: { info: infoStr, hobbies: hobbiesStr }
})
// 接收时
mounted() {
  const info = JSON.parse(this.$route.query.info);
  const hobbies = JSON.parse(this.$route.query.hobbies);
  console.log(info.name); // 小明
  console.log(hobbies[0]); // 篮球
}

这样就能完美传递对象、数组这类复杂数据了~ 简单类型(字符串、数字、布尔)直接传就行,Vue Router会帮你处理编码和解码。

和params参数的核心区别有哪些?

为了让大家更直观理解,列个对比表:

对比项 query参数 params参数
传参方式 path或name配合query对象 必须用name(用path传会被忽略)
url显示 在url中以?key=value形式显示 若路由配置了动态段(如/user/:id),则显示在路径中;否则不显示
刷新保留 刷新后参数还在(因为url包含) 若路由配置了动态段且url显示了参数,刷新保留;否则刷新丢失
路由配置依赖 不需要在路由规则里提前定义 若要在url显示参数,必须在路由path中定义动态段(如/user/:id
参数隐藏性 参数暴露在url上,适合公开分享 若路由没配动态段,参数不暴露在url,适合传隐私数据

实际场景对比

  • 做“商品搜索页”,筛选条件(价格区间、销量排序)适合用query——因为用户可能想把筛选后的链接分享给朋友,query参数在url里,分享后对方打开是一样的结果;
  • 做“用户个人中心”,用户ID这类参数适合用params+动态路由(如/user/:userId)——因为每个用户的页面路径是唯一的,且ID放在路径里更符合RESTful风格,同时刷新也不会丢。

实战中哪些场景适合用query?

理解了query的特性,这些场景用query会很顺手:

列表页→详情页传ID

比如电商系统中,从商品列表点进商品详情,传商品ID,因为详情页需要根据ID请求接口拿数据,刷新后url里的ID还在,能重新请求数据,用户体验更稳。

搜索页的筛选条件

比如知乎的搜索页,筛选“综合、最新、最多赞同”,这些筛选条件会被拼到query里(如?type=latest&page=2),用户刷新页面,筛选条件还在;分享链接给别人,对方打开也是同样的筛选结果。

分页功能

列表页的页码(page=3)用query传,用户刷新后还在当前页,不会回到第一页,如果用params传(且路由没配动态段),刷新就会丢页码,体验很差。

多tab切换的状态保存

比如后台管理系统的选项卡,当前激活的tab(tab=order)用query存,刷新后tab状态不变,不用用户重新点。

这些场景的共同点是:参数需要“持久化”(刷新或分享后不变),且不需要隐藏参数,用query再合适不过。

常见错误和解决办法

学的时候难免踩坑,把高频错误和解决方法列出来,避坑效率更高:

错误:传了query但url没变化

原因:可能用了path传参却错误地写了params(params和path一起用会被Vue Router忽略),或者to的对象语法写错了。
解决:检查to的对象里是不是用了params而不是query,确保是query: { ... }

错误:接收不到query参数

原因:把this.$route.query写成了this.$router.query(混淆了$route和$router)。
解决:route是“当前路由信息”,用来读参数;$router是“路由实例”,用来做跳转,接收参数一定用this.$route.query

错误:复杂数据传过去变成[object Object]

原因:url只能存字符串,对象、数组这类复杂类型直接传会被强制转成字符串,导致信息丢失。
解决:传参前用JSON.stringify转成字符串,接收时用JSON.parse转回来。

错误:刷新后query参数丢失

原因:极大概率是把query参数当成params传了(比如路由没配动态段,却用params传参),或者传参时没把query放到url里。
解决:确认传参方式是query,且用path或name配合query对象传参,确保url里有后的参数。

写在最后

Vue2 Router的query参数看似简单,实际涉及传参、接收、类型处理、和params的区别等多个细节,把这些知识点吃透,不管是做页面跳转传参,还是处理刷新、分享等场景,都能游刃有余,如果还有其他疑问,评论区留言,咱们一起讨论~

版权声明

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

发表评论:

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

热门