Vue3
Node.js
TypeScript
路由
接口请求
状态管理
实战项目
求职与未来发展
$$tip
本章主要介绍为什么会有两种模式和它们的机制,有关两种模式的配置可以参考官方文档,不同的历史记录模式。
$$
以下是指向同一个页面的两种模式的链接。
https://example.com/#/user // hash
https://example.com/user // HTML5
为什么存在两种模式?
通常来说,我们平时的文件跟域名路径都是一一对应的,比如以下的文件目录,对应到域名路径上就应该如下。
https://example.com // 显示 index.html 文件
https://example.com/index.html // 显示 index.html 文件
https://example.com/user.html // 显示 user.html 文件
https://example.com/about.html // 显示 about.html 文件
问题来了, Vue 打包生成的页面只有一个 index.html
文件。
如下图, dist
文件夹是运行 npm run build
打包后生成的文件目录,可见只有一个 index.html
文件。这也 Vue 被称为单页面应用(single page web application,SPA)。
那么是否意味着 Vue 都只能有一个页面了呢,不是的。 通过 hash 模式的链接,会把所有的页面请求都指向 index.html
文件,因为 #
本质上只是一个锚定位。
$$jsdemo$$
$$edit$$
const url = new URL("https://example.com/#/user")
alert(url.pathname) // 打印(/),文件指向 index.html
alert(url.hash) // 打印(#/user)
hash 模式
我们可以简单用原生的前端代码通过 hash 模式实现多个页面的效果。
<!-- index.html -->
<div id="app"></div>
<script>
// hash 模式
switch (document.location.hash) {
case "#/":
app.outerHTML = "<h1>首页</h1>"
break
case "#/user":
app.outerHTML = "<h1>用户页面</h1>"
break
case "#/about":
app.outerHTML = "<h1>关于页面</h1>"
break
default:
app.outerHTML = "<h1>404,未找到页面。</h1>"
break
}
</script>
代码虽简陋,但也表明 Vue Router 中 hash 模式的机制。
HTML5 模式
由于 hash 模式终究只是锚定位,一是链接不雅观,与传统链接有区别,二是不利于 SEO(搜索引擎优化),因为搜索引擎爬虫会把所有锚定位的链接当成一个页面。
因此便有了 HTML5 模式。
<!-- index.html -->
<div id="app"></div>
<script>
// HTML5 模式
switch (document.location.pathname) {
case "/":
app.outerHTML = "<h1>首页</h1>"
break
case "/user":
app.outerHTML = "<h1>用户页面</h1>"
break
case "/about":
app.outerHTML = "<h1>关于页面</h1>"
break
default:
app.outerHTML = "<h1>404,未找到页面。</h1>"
break
}
</script>
问题又来了,通过路径的形式那么服务器会返回对应的文件,比如以上会分别返回 user
、 about
文件等等。这些文件在服务器中并不存在,那么只会返回 404 错误(找不到对应文件)。
因此,使用 HTML5 模式必须配置服务器的相关代理工具,使其任何路径都指向 index.html
文件,然后再在 index.html
根据链接的路径名返回对应的页面内容。
查看 Vue Router 官方文档中对于 HTML5 模式的服务器配置示例。