1️⃣ hash 路由的原理

  1. <body>
  2. <!-- router-link -->
  3. <a href="#/">首页</a>
  4. <a href="#/about">关于</a>
  5. <!-- 如果标签不是 a 标签的话就要监听点击事件传值 -->
  6. <p onclick="handleClick('/')">首页</p>
  7. <p onclick="handleClick('/about')">关于</p>
  8. <!-- router-view -->
  9. <div id="view"></div>
  10. <script>
  11. document.addEventListener('DOMContentLoaded', () => {
  12. view.innerHTML = location.hash.slice(1)
  13. })
  14. window.addEventListener('hashchange', () => {
  15. view.innerHTML = location.hash.slice(1)
  16. })
  17. function handleClick(address) {
  18. location.hash = address
  19. }
  20. </script>
  21. </body>

动画5.gif

1️⃣ history 路由的原理

  1. <body>
  2. <!-- router-link -->
  3. <p onclick="handleClick('/')">首页</p>
  4. <p onclick="handleClick('/about')">关于</p>
  5. <!-- router-view -->
  6. <div id="view"></div>
  7. <script>
  8. document.addEventListener('DOMContentLoaded', () => {
  9. view.innerHTML = location.pathname;
  10. })
  11. function handleClick(address) {
  12. window.history.pushState(null, null, address);
  13. view.innerHTML = location.pathname;
  14. }
  15. window.onpopstate = function () {
  16. view.innerHTML = location.pathname;
  17. }
  18. </script>
  19. </body>

动画6.gif

1️⃣ hash 和 history 的区别

hash —— 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。比如这个 URL:http://www.abc.com/#/hello hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
因此可以说,hash 模式和 history 模式都属于浏览器自身的特性,Vue-Router 只是利用了这两个特性(通过调用浏览器提供的接口)来实现前端路由.

1️⃣ 总结

hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.abc.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.abc.com/book/id 如果后端缺少对 /book/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”
结合自身例子,对于一般的 Vue + Vue-Router + Webpack + XXX 形式的 Web 开发场景,用 history 模式即可,只需在后端(Apache 或 Nginx)进行简单的路由配置,同时搭配前端路由的 404 页面支持。