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

vue-router里的query params该怎么用?

terry 6小时前 阅读数 9 #Vue
文章标签 router query params

不少刚接触Vue路由的同学,对query params总是又好奇又有点懵——它到底是干啥的?传参咋传?接收咋接?和params有啥不一样?这篇文章就用问答的方式,把vue-router里query params的关键知识点掰碎了讲清楚,帮你理顺思路~

query params到底是URL里的啥“玩意儿”?

简单说,query params是URL中后面跟着的键值对组合,比如打开链接 https://xxx.com/user?name=张三&age=18 ,这里的 name=张三age=18 就是query params。

在vue-router里,它是路由传参的一种方式,特点很明显:

  • 不用在路由规则里提前定义:哪怕你路由配置只写了 { path: '/user' } ,照样能传query params;
  • 刷新页面不会丢数据:因为参数明明白白写在URL里了,刷新时浏览器会保留这部分;
  • 支持多参数组合:想传几个键值对都行,用 & 分隔开就行。

举个实际场景:做商品列表的筛选功能时,“价格区间”“品牌”这些筛选条件就适合存在query params里,用户筛选后URL会带上这些参数,不仅自己刷新页面能保留筛选状态,分享给朋友也能直接打开同样筛选后的页面~

给路由传query params,有哪几种方式?

vue-router里传query params分编程式导航声明式导航两种方式,本质都是给路由对象的 query 字段赋值。

编程式导航(用代码跳转)

在组件里通过 this.$router.push() 跳转时,给对象里的 query 传参,比如从首页跳转到用户页并传参:

// Vue2示例
this.$router.push({
  path: '/user', 
  query: { name: '张三', age: 18 }
})
// Vue3示例(组合式API)
import { useRouter } from 'vue-router'
const router = useRouter()
router.push({
  path: '/user', 
  query: { name: '张三', age: 18 }
})

跳转后URL就会变成 /user?name=张三&age=18

声明式导航(用组件)

在模板里用 时,通过 :to 绑定一个对象,给 query 传参:

<router-link 
  :to="{ 
    path: '/user', 
    query: { name: '张三', age: 18 } 
  }"
>
  去用户页
</router-link>

点击这个链接,效果和编程式导航一样,URL会带上query params~

小提醒:传参时用 path 还是 name
如果用 name(路由的命名),可以和 params 配合,但query和path/name都能兼容

router.push({
  name: 'User', // 假设路由配置里name是'User'
  query: { name: '张三' }
})

这种方式更灵活,推荐优先用 name 跳转~

页面里咋拿到传过来的query params?

不管是Vue2还是Vue3,都是通过路由实例query 属性获取,只不过获取方式略有不同。

Vue2 选项式API

在组件里直接用 this.$route.query ,比如在 mounted 钩子或者方法里:

export default {
  mounted() {
    console.log(this.$route.query.name) // 输出“张三”
    console.log(this.$route.query.age)  // 输出“18”(注意:这里是字符串!)
  }
}

Vue3 组合式API

需要先导入 useRoute ,再获取路由实例:

<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.query.name) // 输出“张三”
console.log(route.query.age)  // 输出“18”(同样是字符串)
</script>

关键细节:query params里的所有值都是字符串!
如果传的是数字(age: 18 ),接收时拿到的是 '18' ,需要自己转成Number类型,比如做分页功能时,page=2 传过去,接收后要转成数字再请求接口:

const page = Number(route.query.page) // 把字符串转成数字

query params变了,组件咋没反应?咋解决?

比如从 /user?tab=info 跳转到 /user?tab=setting ,页面还是同一个组件(User.vue),这时候Vue不会重新创建组件实例,生命周期钩子(mounted )也不会再执行,所以组件里的数据不会自动更新。

解决办法有两种:

方法1:用watch监听路由变化

Vue2里在 watch 里监听 $route

export default {
  watch: {
    '$route'(newRoute, oldRoute) {
      // newRoute.query里就是最新的参数
      console.log(newRoute.query.tab) 
    }
  }
}

Vue3组合式API里用 watch 监听 route

<script setup>
import { useRoute, watch } from 'vue-router'
const route = useRoute()
watch(route, (newRoute) => {
  console.log(newRoute.query.tab)
})
</script>

方法2:用导航守卫beforeRouteUpdate

Vue2里可以在组件内写导航守卫:

export default {
  beforeRouteUpdate(to, from, next) {
    // to.query里是新的参数
    console.log(to.query.tab)
    next() // 必须调用next()放行
  }
}

Vue3里因为组合式API没有组件内守卫,更推荐用 watch

举个实际场景:用户在个人中心切换“基本信息”“设置”标签,URL里的 tab 参数变化时,组件要根据新的 tab 加载不同内容,这时候监听query变化就很关键~

query params和params有啥核心区别?

很多同学会把这俩搞混,其实从**位置、路由配置、刷新表现**这三点就能分清:
对比项 query params params
URL里的位置 在?后面(如/user?name=xxx) 在路径里(如/user/:id → /user/123)
路由配置要求 不需要提前定义路由规则 必须在路由里写/:参数名(如{ path: '/user/:id' })
刷新页面后 参数保留(因为在URL可见) 若没配置在路由里,刷新会丢失
传参方式 用query字段传参 用params字段传参(且必须用name跳转)

举个栗子理解:

  • 用户ID这种必须出现在URL路径里的信息,适合用params(/user/123 ,123是用户ID);
  • 筛选条件、分页、标签切换这种可选、灵活的参数,适合用query(/goods?price=100-200&brand=苹果 )。

实际开发中query params有哪些实用场景?

query params的灵活性,让它在很多场景下都能帮我们解决问题,举几个高频场景:

场景1:搜索与筛选

电商网站的商品列表页,用户选了“价格区间100-200”“品牌苹果”,把这些条件存在query params里,URL就变成 /goods?price=100-200&brand=苹果 ,这样用户刷新页面、分享链接,都能保留筛选状态~

场景2:分页功能

列表页的分页,把 page=2 存在query里,URL变成 /list?page=2 ,不仅刷新不会丢页码,SEO也更友好(搜索引擎能索引到不同页码的页面)~

场景3:多tab切换

个人中心的“订单”“收藏”“设置”标签,用 tab=ordertab=favorite 存在query里,切换时URL变化,组件根据tab加载对应内容~

场景4:临时状态保存

多步骤表单(比如注册分“填写信息”“验证手机”“设置密码”三步),第一步填的信息可以存在query里,跳转到第二步时带着这些参数,回来还能恢复表单内容~

怎么优化query params的使用体验?

虽然query params很好用,但参数太多会让URL又长又乱,还可能影响性能和SEO,这时候可以做这些优化:

优化1:精简参数,避免冗余

传参时过滤掉空值或默认值,比如搜索关键词为空时,别把 keyword= 塞到URL里;分页默认是第1页时,也别传 page=1 ,可以用对象过滤:

const query = { 
  keyword: this.keyword || undefined, 
  page: this.page === 1 ? undefined : this.page 
}
// 这样空值或默认值会被自动过滤,URL更干净
router.push({ path: '/search', query })

优化2:参数加密(可选)

如果query里有敏感信息(比如临时token),可以加密后再传,接收时解密,但注意:加密不是绝对安全,只是避免URL明文暴露~

优化3:配合路由元信息做权限

在路由配置的 meta 里定义规则,比如某些query参数下需要登录:

{
  path: '/private',
  name: 'Private',
  component: PrivatePage,
  meta: { 
    requiresAuth: true,
    // 额外规则:query里必须有token
    needToken: (route) => !!route.query.token 
  }
}

然后在全局守卫里判断,增强权限控制~

优化4:利用query params做SEO

因为query params在URL里,搜索引擎能识别不同参数对应的页面,比如博客的标签页 /blog?tag=前端 ,合理配置meta标签和页面内容,能让搜索引擎收录每个标签下的文章,提升曝光~

看完这些问题,是不是对vue-router的query params清晰多了?其实核心就是理解它在URL里的表现、传参接收的方式,以及和params的区别,实际项目里多结合场景用一用,比如做个带筛选的列表页,或者多tab的页面,很快就能掌握规律~要是还有疑问,评论区随时聊~

版权声明

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

发表评论:

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

热门