为什么vue中使用query可以保留参数
本质与原理
一句话回答:
这是 Vue Router 将 query 对象序列化为 URL 查询字符串(Query String) ,并拼接到路径后面,形成完整的 URL(如 /user?id=123&name=alice),从而实现参数传递。
本质:前端路由对 URL 的构造与解析
Vue Router 并不“保存”参数,而是:
- 构造一个合法的 URL
- 通过浏览器 History API 或 hash 变更 URL
- 在路由匹配时反向解析该 URL
所以,query 的存在完全依赖于 URL 本身的结构。
🛠 执行过程详解
当你调用:
this.$router.push({
path: '/user',
query: { id: 123, name: 'alice' }
});
Vue Router 内部会执行以下步骤:
1:序列化 query 对象
- 使用类似
URLSearchParams的机制,将{ id: 123, name: 'alice' }转为字符串:
// 伪代码
const queryString = new URLSearchParams({ id: 123, name: 'alice' }).toString();
// 结果: "id=123&name=alice"
2:拼接完整 URL
- 将
path和queryString合并:
/user + ? + id=123&name=alice → /user?id=123&name=alice
3:触发 URL 变更
- 根据当前模式(
hash或history):
-
-
Hash 模式:设置
location.hash = '#/user?id=123&name=alice' -
History 模式:调用
history.pushState(null, '', '/user?id=123&name=alice')
-
Hash 模式:设置
✅ 此时,浏览器地址栏显示完整带参 URL,且页面不刷新。
4:路由匹配与参数注入
- Vue Router 监听到 URL 变化后:
-
- 匹配路由(如
{ path: '/user', component: User }) - 解析查询字符串,还原为对象:
- 匹配路由(如
this.$route.query === { id: "123", name: "alice" }
⚠️ 注意:所有 query 值都是 字符串类型(HTTP 协议限制)
为什么可以“带上路径后面”?
因为这是 URL 标准的一部分!
根据 RFC 3986,URL 结构如下:
https://example.com/user?id=123&name=alice
│ │ │ └───────────────┘
│ │ │ ↑
│ │ │ Query String(查询字符串)
│ │ └── Path(路径)
│ └── Host(主机)
└── Scheme(协议)
-
查询字符串(
?key=value&...)是 URL 的合法组成部分 - 浏览器天然支持它,刷新时会完整保留
- 服务端和前端都可以读取它
💡 Vue Router 只是利用了这一标准机制,并没有发明新东西。
优势:为什么推荐用 query 传参?
| 特性 | 说明 |
|---|---|
| 可分享 | 完整 URL 可直接复制发送给他人 |
| 可刷新 | 刷新后参数仍在(因为 URL 没变) |
| 可书签 | 用户可收藏带参链接 |
| SEO 友好 | 搜索引擎能索引不同 query 的页面(如搜索结果页) |
| 调试方便 | 地址栏直接可见参数 |
注意事项
- 值类型全是字符串
// 传入
query: { id: 123 } // number
// 接收
this.$route.query.id === "123" // string!
需要手动转换:parseInt(this.$route.query.id)
- 敏感信息不要放 query
-
- 查询字符串会出现在:
-
-
- 浏览器历史记录
- 服务器日志
- Referer 头(如果跳转到第三方)
-
-
- 不适合放 token、密码等
- 长度有限制
-
- URL 总长一般限制在 2048 字符以内(各浏览器不同)
- 大量数据建议用 POST 或状态管理
对比:query vs params(非路径型)
| 方式 | 是否体现在 URL | 刷新后保留 | 适用场景 |
|---|---|---|---|
query |
✅ 是(?id=123) |
✅ 是 | 公开、可分享、可刷新的参数 |
params(未在 path 声明) |
❌ 否 | ❌ 否 | 临时跳转(如表单步骤),但刷新丢失 |
总结
this.$router.push({ path: '/user', query: {...} }) 的本质是:
构造一个标准的、带查询字符串的 URL,并通过前端路由机制导航到该地址。
- 它利用的是 URL 原生的查询参数机制
- 参数被持久化在地址栏中,因此刷新不丢失
- 这是 SPA 应用中最安全、最通用的传参方式之一
🌟 记住:只要参数需要“跨刷新”或“可分享”,优先用 query !