Vue-Router 哈希路由 vs 历史路由详解

一、核心区别概览

特性 哈希模式 (hash mode) 历史模式 (history mode)
URL 格式 http://example.com/#/home http://example.com/home
原理 监听 hashchange 事件 使用 History API (pushState/replaceState)
兼容性 IE8+ IE10+
服务器配置 无需特殊配置 需要配置支持
SEO 不友好 友好(需要 SSR 配合)

二、哈希模式 (Hash Mode)

  1. 实现原理
javascript 复制代码
// Vue Router 内部实现简化版
class HashRouter {
  constructor() {
    // 1. 监听 hashchange 事件
    window.addEventListener('hashchange', () => {
      this.handleHashChange(window.location.hash);
    });
    
    // 2. 初始加载
    window.addEventListener('load', () => {
      if (!window.location.hash) {
        window.location.hash = '/';
      }
    });
  }
  
  handleHashChange(hash) {
    // 去除 # 号
    const path = hash.slice(1) || '/';
    // 路由匹配和渲染...
  }
  
  push(path) {
    window.location.hash = path;
  }
}
  1. 特点分析
javascript 复制代码
// URL 示例
// 完整URL: https://example.com/#/user/profile
console.log(window.location);
/*
{
  href: "https://example.com/#/user/profile",
  hash: "#/user/profile",     // 路由信息在这里
  pathname: "/",              // 始终是根路径
  search: "",                 // 查询参数在hash前
  hostname: "example.com"
}
*/

// 哈希变化不会触发页面刷新
// 只会触发 hashchange 事件
window.onhashchange = function(event) {
  console.log('旧URL:', event.oldURL);
  console.log('新URL:', event.newURL);
};
  1. 配置方式
javascript 复制代码
// Vue Router 配置
import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),  // 使用哈希历史
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About }
  ]
})

三、历史模式 (History Mode)

  1. 实现原理
javascript 复制代码
// Vue Router 内部实现简化版
class HistoryRouter {
  constructor() {
    // 1. 监听 popstate 事件(浏览器前进后退)
    window.addEventListener('popstate', (event) => {
      this.handlePopState(event.state);
    });
    
    // 2. 拦截链接点击(阻止默认行为)
    document.addEventListener('click', (e) => {
      if (e.target.tagName === 'A' && e.target.href) {
        e.preventDefault();
        this.push(e.target.getAttribute('href'));
      }
    });
  }
  
  push(path) {
    // 使用 History API 添加记录
    window.history.pushState({ path }, '', path);
    // 手动触发路由更新
    this.updateRoute(path);
  }
  
  replace(path) {
    window.history.replaceState({ path }, '', path);
    this.updateRoute(path);
  }
  
  handlePopState(state) {
    this.updateRoute(state?.path || window.location.pathname);
  }
}
  1. History API 详解
javascript 复制代码
// 核心 API 方法

// 1. pushState - 添加历史记录(不会触发页面刷新)
history.pushState(state, title, url);
// 示例:
history.pushState({ page: 1 }, "Page 1", "/page1");

// 2. replaceState - 替换当前历史记录
history.replaceState(state, title, url);
// 示例:
history.replaceState({ page: 2 }, "Page 2", "/page2");

// 3. popstate 事件 - 监听前进后退
window.addEventListener('popstate', (event) => {
  console.log('位置变化到:', event.state);
});

// 4. 获取当前状态
const currentState = history.state;
  1. 配置方式
javascript 复制代码
// Vue Router 配置
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),  // 使用 HTML5 历史模式
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
    { path: '/:pathMatch(.*)*', component: NotFound } // 404页面
  ]
})

四、服务器配置差异

  1. 哈希模式(无需配置)
bash 复制代码
# 所有请求都返回 index.html
# 哈希部分由前端处理
https://example.com/#/about  → 返回 index.html
https://example.com/#/user/1 → 返回 index.html
  1. 历史模式(必须配置)

nginx文件

bash 复制代码
# Nginx 配置示例
server {
    listen 80;
    server_name example.com;
    root /usr/share/nginx/html;
    index index.html;
    
    location / {
        try_files $uri $uri/ /index.html;  # 关键:重定向到 index.html
    }
}

apache文件

bash 复制代码
# 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>

javascript文件

javascript 复制代码
// 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'));
});

五、优缺点对比

哈希模式

优点:

兼容性好(支持 IE8+)

无需服务器特殊配置

部署简单,适合静态托管

不会发起服务器请求(hash变化)

缺点:

URL 不美观,有 # 符号

SEO 不友好,爬虫可能忽略 hash 部分

某些锚点功能冲突

历史模式

优点:

URL 美观,无 # 符号

SEO 友好(配合 SSR 更佳)

完整的 URL 路径语义

可以利用完整的 URL 进行分享

缺点:

需要服务器支持(所有路由返回 index.html)

兼容性要求 IE10+

部署配置相对复杂

相关推荐
C_心欲无痕2 小时前
Next.js 的哲学思想
开发语言·前端·javascript·ecmascript·nextjs
a程序小傲2 小时前
哈罗Java面试被问:布隆过滤器的误判率和哈希函数选择
java·服务器·算法·面试·职场和发展·哈希算法
海鸥两三2 小时前
登录页面form表单
前端·javascript·css
[H*]2 小时前
Flutter框架跨平台鸿蒙开发——Pattern Matching模式匹配
android·javascript·flutter
玫城11 小时前
[ VUE ] 封装通用数组校验组件,el-input内使用
前端·javascript·vue.js
弓.长.16 小时前
React Native 鸿蒙跨平台开发:实现一个多功能单位转换器
javascript·react native·react.js
南半球与北海道#16 小时前
前端打印(三联纸票据打印)
前端·vue.js·打印
摘星编程16 小时前
React Native for OpenHarmony 实战:ToggleSwitch 切换开关详解
javascript·react native·react.js
满栀58516 小时前
分页插件制作
开发语言·前端·javascript·jquery