1. Hash 模式
index.ts
import { createRouter, createWebHistory, RouteRecordRaw, createWebHashHistory } from "vue-router";
// 路由模式
//vue2 mode history -> vue3 createWebHistory
//vue2 mode hash -> vue3 createWebHashHistory
//vue2 mode abstact -> vue3 createMemoryHistory
const routes: Array<RouteRecordRaw> = [
{
path: "/",
component: () => import("../components/login.vue")
},
{
path: "/reg",
component: () => import("../components/reg.vue")
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router

hash实现
hash是URL中hash()及后面的那部分,常用作描点在页面内进行导航,改变URL中的hash部分不会引起页面刷新
通过hashchange事件监听URL的变化,改变URL的方式只有这几种:
- 通过浏览器前进后退改变URL
- 通过
<a>标签改变URL - 通过window.location改变URL


2. HTML5 模式
index.ts
import { createRouter, createWebHistory, RouteRecordRaw, createWebHashHistory } from "vue-router";
// 路由模式
//vue2 mode history -> vue3 createWebHistory
//vue2 mode hash -> vue3 createWebHashHistory
//vue2 mode abstact -> vue3 createMemoryHistory
const routes: Array<RouteRecordRaw> = [
{
path: "/",
component: () => import("../components/login.vue")
},
{
path: "/reg",
component: () => import("../components/reg.vue")
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router

history实现
Vue Router 的 history 模式使用的是 HTML5 的 History API,例如 pushState 和 replaceState,来改变 URL 而无需重新加载页面。
history提供类似hashchange事件的popstate事件,但popstate事件有些不同:
- 通过浏览器前进后退改变URL时会触发popstate事件
- 通过pushState/replaceState或
<a>标签改变URL不会触发popstate事件 - 好在我们可以拦藏pushState/replaceState的调用和
<a>标签的点击事件来检测URL变化 - 通过js调用history的back,go,forward方法触发该事件
所以监听URL变化可以实现,只是没有hashchange那么方便


但此时切换路径后并不会被监听,需要刷新页面。
history 模式怎么解决刷新 404 的问题?
history 模式刷新时会出现 404 错误 。因为在 history 模式下,URL 不包含哈希(#)。当用户在客户端导航时,Vue Router 提供的组件和 URL 是同步的,但当用户刷新页面或直接输入地址时,这个请求会直接发送到服务器,而服务器端通常不知道如何处理这些前端路由,导致 404 错误。
解决办法:
服务器设置:为了解决刷新 404 的问题,服务器需要进行特殊配置,将所有的请求都重定向到一个入口文件。以典型的 Nginx 服务器为例,可以通过以下配置来实现:
location / {
try_files $uri $uri/ /index.html;
}
上述配置会尝试找到请求的文件,如果文件不存在,则将请求重定向到 index.html,由前端的 Vue Router 继续处理路由。
- try_files $uri $uri/ /index.html; 表示:
- 先尝试访问 URL 对应的文件 $uri。
- 如果找不到文件,则尝试访问目录 $uri/。
- 如果还是找不到,则将请求转发到 index.html,由前端路由来处理。
可以在 Express 应用的路由设置中添加处理所有非静态文件的请求,以 Vue Router 的示例: `
const express = require('express');
const path = require('path');
const app = express();
// Serve static files
app.use(express.static(path.join(__dirname, 'dist')));
// Handle SPA
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
// Start server
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
3. Memory 模式
Memory 模式不会假定自己处于浏览器环境,因此不会与 URL 交互也不会自动触发初始导航。
这使得它非常适合 Node 环境和 SSR。它是用 createMemoryHistory() 创建的,并且需要你在调用 app.use(router) 之后手动 push 到初始导航。
import { createRouter, createMemoryHistory } from 'vue-router'
const router = createRouter({
history: createMemoryHistory(),
routes: [
//...
],
})
虽然不推荐,你仍可以在浏览器应用程序中使用此模式,但请注意它不会有历史记录,这意味着你无法后退或前进。
总结
-
Hash 模式:
- 示例:
http://example.com/#/user/1 - 工作原理: 在 URL 中使用哈希(#)来表示路由,所有的路由都会在 URL 的哈希部分进行解析。浏览器不会向服务器发送请求,因此不会重新加载,只会更新hash值,触发路由变化,渲染对应组件。
- 优点:
- 兼容性好:支持大多数浏览器,包括老版本。
- 部署简单:项目打包前端自测可以看到内容,不需要特殊的服务器配置,不需要后端支持。
- 缺点:
- 不利于 SEO:搜索引擎爬虫通常不会处理哈希路由(不处理 URL 中 # 后面的内容)。
- URL 不够友好:URL 中包含哈希,看起来可能不太美观。
- 示例:
-
History 模式:
- 示例:
http://example.com/user/1 - 工作原理: 使用 HTML5 的 History API 来管理路由和浏览历史记录,不再依赖于哈希。此时,URL 中不带有 # ,使用真实的 URL 来作为路由路径。
- 优点:
- 用户体验好:URL 更加友好,没有哈希(#)部分。
- SEO 友好:搜索引擎可以处理路由。
- 缺点:
- 兼容性问题:需要 HTML5 支持,不支持一些老版本浏览器(如 IE9 及以下)。
- 需要特殊服务器配置:因为 History 模式在用户刷新页面时会向服务器发起请求,需要服务器配置以支持前端路由的历史记录。
- 项目打包前端自测默认看不到内容。
- 示例:
如何选择路由模式:
- 如果应用程序需要兼容性好且不需要考虑服务器配置,可以选择 Hash 模式。
- 如果应用程序需要更友好的 URL 和更好的 SEO,可以选择 History 模式,但需要注意兼容性问题和服务器配置。
- 如果是非浏览器环境下的应用程序或者只需要使用编程式导航的情况,可以考虑 Abstract 模式。
大多数现代项目会选择 History 模式,因为它提供了更好的用户体验和 SEO 优势。但在特殊情况下,其他模式也可能更适合。

3202

被折叠的 条评论
为什么被折叠?



