vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue router hash和history区别

Vue Router 中 Hash和 History 模式的核心区别、使用场景

作者:涔溪

文章详细介绍了VueRouter中Hash模式和History模式的核心区别、底层原理、使用场景及部署注意事项,文章还提供了实战部署的解决方案和选型建议,感兴趣的朋友跟随小编一起看看吧

深入理解 Vue Router 中 Hash 模式History 模式 的核心区别、底层原理、使用场景及部署注意事项,我会从「本质→原理→实战→对比→问题解决」全维度超详细讲解,结合你的项目场景(比如之前部署 History 模式报 404)帮你彻底吃透。

一、先搞懂:前端路由的核心本质

Vue 是单页应用(SPA),整个项目只有一个 index.html 文件。前端路由的核心目的:通过 JavaScript 监听 URL 变化,不刷新页面的前提下,动态渲染不同的组件,模拟 “多页面跳转” 的体验(无需向后端发起新的页面请求)。

Hash 模式和 History 模式是实现前端路由的两种技术方案,核心差异在于「URL 表现形式」「底层实现原理」「服务器部署要求」。

二、Hash 模式(哈希模式)

1. 核心定义

Hash 模式是利用 URL 中 # 后面的「哈希值」实现路由跳转,# 是浏览器的锚点标识,哈希值不会被发送到服务器

2. 底层实现原理

(1)核心 API:window.onhashchange

浏览器天生支持监听 # 后面内容的变化,触发 hashchange 事件,前端可在该事件中判断哈希值,渲染对应组件:

// 原生 JS 模拟 Hash 路由核心逻辑
window.addEventListener('hashchange', () => {
  // 获取当前哈希值(去掉 #)
  const hash = window.location.hash.slice(1); 
  // 根据哈希值渲染不同组件
  if (hash === '/proOrder') {
    renderProOrderComponent();
  } else if (hash === '/home') {
    renderHomeComponent();
  }
});

(2)路由跳转的本质

3. Vue Router 中配置 Hash 模式

// router/index.ts
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [/* 你的路由规则 */];
const router = createRouter({
  history: createWebHashHistory(import.meta.env.BASE_URL), // 核心:Hash 模式
  routes
});
export default router;

4. 核心特点(优缺点)

优点缺点
1. 无需后端配置:哈希值不发服务器,直接访问 http://xxx.com/#/proOrder 不会 404;2. 兼容性极好:支持所有浏览器(包括 IE6/7/8);3. 开发便捷:本地 / 线上部署无需协调后端;1. URL 不美观:带 # 符号,用户体验略差;2. SEO 不友好:部分搜索引擎爬虫会忽略 # 后的内容,影响页面收录;3. 锚点冲突:若页面内有原生锚点(如 <a href="#top">),会和路由哈希冲突;

三、History 模式(HTML5 历史模式)

1. 核心定义

History 模式基于 HTML5 新增的 History API 实现,URL 无 #,和传统后端路由的 URL 格式一致,哈希值会被完整发送到服务器

2. 底层实现原理

(1)核心 API:HTML5 History API

(2)路由跳转的本质

// 原生 JS 模拟 History 路由核心逻辑
// 点击跳转按钮时
document.querySelector('#toProOrder').addEventListener('click', (e) => {
  e.preventDefault(); // 阻止默认a标签跳转
  // 修改 URL 为 /proOrder,不发请求
  history.pushState({}, '', '/proOrder');
  // 手动渲染对应组件
  renderProOrderComponent();
});
// 监听回退/前进
window.addEventListener('popstate', () => {
  const path = window.location.pathname;
  if (path === '/proOrder') {
    renderProOrderComponent();
  }
});

⚠️ 关键:pushState 只是修改 URL,不会触发页面刷新,但直接访问 / 刷新 http://xxx.com/proOrder 时,浏览器会向服务器发送该路径的请求—— 这也是你之前部署报 404 的核心原因!

3. Vue Router 中配置 History 模式

// router/index.ts(你的原有配置)
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [/* 你的路由规则 */];
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL), // 核心:History 模式
  routes
});
export default router;

4. 核心特点(优缺点)

优点缺点
1. URL 美观:无 #,符合用户对 URL 的认知习惯;2. SEO 友好:完整 URL 会被搜索引擎收录,利于网站优化;3. 无锚点冲突:和页面内原生锚点(如 #top)互不干扰;1. 需要后端配置:直接访问子路由(如 /proOrder)会触发服务器请求,服务器未配置时返回 404;2. 兼容性一般:仅支持 IE10+ 及现代浏览器;3. 部署成本高:需协调后端修改 Nginx/Apache 配置;

四、Hash 模式 vs History 模式 核心对比表

对比维度Hash 模式History 模式
URL 格式http://xxx.com/#/proOrder(带 #)http://xxx.com/proOrder(无 #)
底层原理监听 window.onhashchange 事件基于 HTML5 history.pushState/replaceState + popstate 事件
服务器请求# 后的内容不发送到服务器,仅请求 index.html完整 URL 发送到服务器,请求 /proOrder 路径
部署要求无需后端配置,直接部署即可必须配置后端(Nginx/Apache),将所有路由转发到 index.html
兼容性全浏览器兼容(IE6+)仅支持 IE10+ 及现代浏览器
SEO 友好性差(爬虫忽略 # 后内容)优(完整 URL 被收录)
锚点冲突易和页面内锚点(#top)冲突无冲突
历史记录基于浏览器哈希历史,自动记录基于 HTML5 History API,可自定义历史记录

五、实战部署:History 模式解决 404 的核心方案

部署 History 模式报 404,本质是 Nginx 未配置「路由转发」,以下是不同后端的配置方案:

1. Nginx 配置(最常用,你的场景)

server {
    listen 80;
    server_name 你的域名/服务器IP;
    root /usr/share/nginx/html/你的项目dist目录; # 项目打包后的根目录
    index index.html index.htm;
    # 核心:所有请求转发到 index.html,由前端路由接管
    location / {
        try_files $uri $uri/ /index.html; # 先找物理文件→找不到就转发到index.html
        add_header Cache-Control "no-cache, no-store, must-revalidate"; # 避免缓存
    }
    # 静态资源缓存(可选,提升加载速度)
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800";
    }
}

2. Apache 配置

修改 .htaccess 文件(放在项目根目录):

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

3. Node.js Express 配置

const express = require('express');
const path = require('path');
const app = express();
// 静态文件目录
app.use(express.static(path.join(__dirname, 'dist')));
// 所有路由转发到 index.html
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
});
app.listen(3000, () => {
  console.log('服务器运行在 3000 端口');
});

六、选型建议:什么时候用 Hash/History?

选 Hash 模式的场景

  1. 内部管理系统(如你的工单系统)、无需 SEO 的项目;
  2. 快速开发、无法协调后端配置服务器;
  3. 需要兼容低版本浏览器(如 IE8 及以下);
  4. 临时部署、测试环境(无需复杂配置)。

选 History 模式的场景

  1. 对外展示的官网、需要 SEO 优化的项目;
  2. 追求 URL 美观,提升用户体验;
  3. 团队能协调后端修改 Nginx/Apache 配置;
  4. 现代浏览器环境(无需兼容低版本 IE)。

七、常见问题 & 解决方案

1. History 模式刷新 404

2. Hash 模式 URL 中的 # 影响锚点

问题:页面内 <a href="#top">回到顶部</a> 会被路由拦截;

解决:Vue Router 可配置hashPrefix自定义哈希前缀(如#!):

const router = createRouter({
  history: createWebHashHistory({ hashPrefix: '!' }), // 哈希前缀改为 #!
  routes
});

此时 URL 为http://xxx.com/#!/proOrder,原生锚点#top不会冲突。

3. History 模式部署在子路径(如/vue3-app)

总结(核心关键点)

  1. Hash 模式:靠 # 分隔,无需后端配置,兼容性好,URL 带 #,SEO 差;
  2. History 模式:基于 HTML5 API,URL 美观,SEO 好,但需后端配置路由转发,否则 404;
  3. 选型核心:对内系统 / 快速开发用 Hash,对外网站 / 需 SEO 用 History;
  4. 你的项目(工单系统):若无需 SEO,用 Hash 模式可避免 Nginx 配置;若追求 URL 美观,按上文配置 Nginx 即可解决 404。

到此这篇关于深入理解 Vue Router 中 Hash 模式和 History 模式 的核心区别、底层原理、使用场景及部署注意事项的文章就介绍到这了,更多相关vue router hash和history区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文