普通视图

发现新文章,点击刷新页面。
昨天 — 2025年12月22日首页

为什么vue中使用query可以保留参数

2025年12月22日 17:04

本质与原理

一句话回答
这是 Vue Router 将 query 对象序列化为 URL 查询字符串(Query String) ,并拼接到路径后面,形成完整的 URL(如 /user?id=123&name=alice),从而实现参数传递。


本质:前端路由对 URL 的构造与解析

Vue Router 并不“保存”参数,而是:

  1. 构造一个合法的 URL
  2. 通过浏览器 History API 或 hash 变更 URL
  3. 在路由匹配时反向解析该 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

  • pathqueryString 合并:
/user + ? + id=123&name=alice → /user?id=123&name=alice

3:触发 URL 变更

  • 根据当前模式(hashhistory):
    • Hash 模式:设置 location.hash = '#/user?id=123&name=alice'
    • History 模式:调用 history.pushState(null, '', '/user?id=123&name=alice')

✅ 此时,浏览器地址栏显示完整带参 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 的页面(如搜索结果页)
调试方便 地址栏直接可见参数

注意事项

  1. 值类型全是字符串

// 传入
query: { id: 123 } // number
// 接收
this.$route.query.id === "123" // string!

需要手动转换:parseInt(this.$route.query.id)

  1. 敏感信息不要放 query
    • 查询字符串会出现在:
      • 浏览器历史记录
      • 服务器日志
      • Referer 头(如果跳转到第三方)
    • 不适合放 token、密码等
  1. 长度有限制
    • URL 总长一般限制在 2048 字符以内(各浏览器不同)
    • 大量数据建议用 POST 或状态管理

对比:query vs params(非路径型)

方式 是否体现在 URL 刷新后保留 适用场景
query ✅ 是(?id=123 ✅ 是 公开、可分享、可刷新的参数
params(未在 path 声明) ❌ 否 ❌ 否 临时跳转(如表单步骤),但刷新丢失

总结

this.$router.push({ path: '/user', query: {...} }) 的本质是:
构造一个标准的、带查询字符串的 URL,并通过前端路由机制导航到该地址。

  • 它利用的是 URL 原生的查询参数机制
  • 参数被持久化在地址栏中,因此刷新不丢失
  • 这是 SPA 应用中最安全、最通用的传参方式之一

🌟 记住:只要参数需要“跨刷新”或“可分享”,优先用 query

vue中hash模式和history模式的区别

2025年12月22日 16:47

一句话总结

  • Hash 模式:利用 URL 中 # 后的内容变化实现前端路由,不触发页面刷新,兼容性好。
  • History 模式:基于 HTML5 的 history.pushState()popstate 事件,URL 更干净,但需要服务端配合。

一、Hash 模式(默认模式)

1. 基本形式

https://example.com/#/user/profilehash 部分

2. 工作原理

  • 核心机制:监听 window.onhashchange 事件。
  • 当用户点击链接或调用 router.push() 时,Vue Router 修改 location.hash(如 #/home#/about)。
  • 浏览器不会向服务器发起请求,因为 # 及其后的内容不会发送给服务器
  • 页面 URL 改变但不刷新,前端根据新的 hash 值匹配路由并渲染对应组件。

3. 特点

优点 缺点
✅ 兼容性极好(IE8+ 支持) ❌ URL 中带有 #,不够美观
✅ 无需服务端配置 ❌ SEO 友好性略差(部分爬虫可能忽略 hash)
✅ 天然避免 404 问题 ❌ 不符合传统 URL 语义

4. 示例代码(Vue Router 配置)

const router = new VueRouter({
  mode: 'hash', // 默认值,可省略
  routes: [...]
});

二、History 模式(推荐用于现代项目)

1. 基本形式

https://example.com/user/profile

URL 看起来和传统多页应用一致,无 # 符号。

2. 工作原理

  • 核心技术
    • history.pushState(state, title, url):在不刷新页面的情况下修改浏览器历史记录和 URL。
    • history.replaceState(...):替换当前历史记录。
    • window.onpopstate:监听浏览器前进/后退操作(如点击 ← → 按钮)。
  • 流程示例
    1. 用户访问 /home → 前端加载,Vue Router 渲染 Home 组件。
    2. 点击“关于”链接 → 调用 router.push('/about') → 执行 history.pushState(null, '', '/about')
    3. URL 变为 https://example.com/about,页面不刷新,About 组件被渲染。
    4. 用户刷新页面 → 浏览器向服务器请求 /about 资源。

3. 关键问题:刷新 404

  • 原因:服务器收到 /about 请求时,若未配置,会尝试查找物理路径下的 about.html 或目录,找不到则返回 404。
  • 解决方案服务端需配置“兜底路由” ,将所有前端路由请求重定向到 index.html

Nginx 配置示例:

location / {
  try_files $uri $uri/ /index.html;
}

4. 特点

优点 缺点
✅ URL 简洁美观,符合 REST 风格 ❌ 需要服务端支持(部署配置)
✅ 更好的 SEO(主流爬虫已支持) ❌ 在纯静态托管(如 GitHub Pages)中需额外处理
✅ 用户体验更接近原生 Web ❌ 旧浏览器(IE9 以下)不支持

5. 示例代码(Vue Router 配置)

const router = new VueRouter({
  mode: 'history',
  routes: [...]
});

🔁 三、对比总结

特性 Hash 模式 History 模式
URL 样式 example.com/#/path example.com/path
刷新是否 404 ❌ 不会(# 后内容不发给服务器) ✅ 会(需服务端配置兜底)
浏览器兼容性 IE8+ IE10+(HTML5 History API)
服务端要求 必须配置 fallback 到 index.html
SEO 友好性 一般 较好(现代爬虫支持)
使用场景 快速原型、老旧环境、无服务端控制权 正式项目、追求用户体验、有运维支持

💡 最佳实践建议

  • 开发阶段:两种模式均可,推荐 history 提前暴露部署问题。
  • 生产部署
    • 若使用 Nginx/Apache/Caddy → 优先选 history + 配置 fallback。
  • 无法控制服务端? → 用 hash 模式最稳妥。

补充知识

  • 为什么 hash 不发给服务器?
    根据 HTTP 规范,URL 中 #fragment 部分仅用于客户端定位(如锚点),不会包含在 HTTP 请求中
  • History API 安全限制
    pushState 只能修改同源下的路径,不能跨域篡改 URL,保障了安全性。

❌
❌