前端路由的两个基本条件

  1. 改变url
  2. 页面不刷新

Hash 路由

  1. hash只作用在浏览器,不会在请求中发送给服务器。
  2. hash发生变化时,浏览器并不会重新给后端发送请求加载页面。
  3. 修改hash时会在浏览器留下历史记录,可以通过浏览器返回按钮回到上一个页面。
  4. hash 发生变化时会触发 hashchange 事件,在该事件中可以通过 window.location.hash 获取到当前 hash 值。

在添加路由的时候添加一个对象,包括url和跳转该地址的处理函数。hashchange 事件可以监听url的变化。

History 路由

利用H5history.pushState()history.replaceState(),分别可以添加和修改历史记录。它们是与 hash 一样具有修改url的功能,之后可以通过windowsonpopstate事件,来监听url的变化,进而处理该url的处理函数。

因为History路由改变的是浏览器的url,因为url改变了,此时如果手动的刷新页面,浏览器会认为是请求一个新的页面,但是新的页面是不存在的(因为url中显示的是通过pushstate加的记录,实际上没有对应的页面),肯定会报错的!

所以需要配合后端,在服务端做url的重定向,就是如果找不到页面,那么就重定向到index.html,vue项目本身就是单页面应用,整个系统也只有一个html

<!--index.html-->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <script src="router.js"></script>
  </head>

  <body>
    <div>
      <button id="btn">点击跳转到 list</button>
      <button id="detail">点击跳转到 detail</button>
    </div>
    <script>
      var router = new Router();

      router.add("/list", function () {
        window.alert("/list路由被添加进来啦");
      });
      router.add("/detail", function () {});

      router.listen();

      var btn1 = document.getElementById("btn");
      btn1.addEventListener("click", function (e) {
        router.push("/list");
      });
      var btn2 = document.getElementById("detail");
      btn2.addEventListener("click", function (e) {
        router.push("/detail");
      });
    </script>
  </body>
</html>
// router.js
function Router() {
  this.routes = [];

  /* 添加路由 */
  this.add = function (re, handler) {
    this.routes.push({ re, handler });
  };

  /* 监听 url 变化  */
  this.listen = function () {
    //路由切换
    window.addEventListener(
      "hashchange",
      function (event) {
        var hash = window.location.hash;
        for (var i = 0; i++; i < this.routes.length) {
          if (hash === this.routes[i].re) {
            this.routes[i].handler.apply({});
          }
        }
      },
      false
    );
  };

  /* 前进到一个新的url  */
  this.push = function (path) {
    window.location.hash = path || "";
  };

  /* 替换成一个新的url  */
  this.replace = function (path) {
    path = path || "";
    var i = window.location.href.indexOf("#");
    window.location.replace(
      window.location.href.slice(0, i >= 0 ? i : 0) + "#" + path
    );
  };

  /* 返回到上一个url  */
  this.back = function () {
    window.history.back();
  };
}

router