Vue - router
- 了解这两种路由模式前,需要清楚 vue - router 的原理是怎样的
- SPA 单页面及应用方式:单一页面应用程序,只有一个完整的页面;他在第一次加载页面时就会将唯一的 html 页面以及其他的页面一起下载下来,这样就能达到切换页面时不会加载整个页面,而是更新某个指定的容器内容
- SPA 的核心之一就是:更新视图而不重新请求页面。
- 路由器对象的实现步骤可以分为三个部分:
- 监听地址栏的变化
- 查找当前路由对应的页面组件
- 将找到的页面组件替换到 router - view 标签所在的位置
- vue - router 在实现单页面前端路由时,提供了两种方式:Hash 和 History 模式。Vue2中是根据mode(mode:hash/history)决定采用那种形式,vue3则是history(history:createWebHistory()/ createWebHashHistory())参数来决定
Hash
- vue - router 默认的就是 Hash 路由模式。使用 Hash 模拟完整的 URL 时,当 URL 发生改变后,页面并不会重新加载;URL 中的 # 就是哈希符或者称为锚点,# 号后面的部分就是哈希值。并且每次哈希值的变化都会在浏览历史中添加一条记录
- 这个 # 以及后面的 哈希值部分都能够通过 window.location.hash 进行读取。哈希值的改变也可以通过 window.addEventListener(‘hashchange’, () => { }) 进行监听
特点
- URL 中存在 # 号
- URL 发生改变时不会触发页面的重新加载(并且这个改变可以被window.history记录)
- HASH 虽然出现在了路由中但不会被包含在 HTTP 请求中,因此 HASH 的改变不会重新加载页面
History
- history 则是路由的另一种模式。它利用了 H5 History Interface 中新增的 pushState 和 replaceState 两个方法
- 这两个方法是基于 back、go、forword 之上,提供了对于历史记录栈修改的功能。只是虽然它们能够修改 URL,但浏览器不会向后端发送请求
- history路由的变化使用 popstate 进行监听
特点
- 通过pushState、replaceState实现无刷新跳转的功能。
- 不带 # 在大部分人看来要比 hash 路由好看许多。
- 兼容性没有 hash 好
History路由生产环境下存在的问题
因为 history 模式的时候路径会随着 http 请求发送给服务器,项目打包部署时,需要后端配置 nginx,当应用通过 vue-router 跳转到某个页面后,因为此时是前端路由控制页面跳转,虽然url改变,但是页面只是内容改变,并没有重新请求,所以这套流程没有任何问题。但是,如果在当前的页面刷新一下,此时会重新发起请求,如果 nginx 没有匹配到当前url,就会出现404的页面。
那为什么hash模式不会出现这个问题呢?
hash 虽然可以改变URL,但不会被包括在 HTTP 请求中。它被用来指导浏览器动作,并不影响服务器端,因此,改变 hash 并没有改变URL,所以页面路径还是之前的路径,nginx 不会拦截。 因此,切记在使用 history 模式时,需要服务端允许地址可访问,否则就会出现404的尴尬场景。
解决方式
要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回到 首页
总结
简单来讲就是,hash 路由兼容梗好,但是带#显得丑些, histroy 和正常 url 路径一样,但是需要在服务器进行单独配置。