路由:通过互联的网络把信息从源地址传输到目的地址的活动
路由表(routing table):存储着指向特定网络地址的路径
路由器:

默认路由

没有指定路由地址时跳到默认地址

404 路由

当路由地址不存在时跳到 404 界面

嵌套路由

在一层路由下再路由

路由模式

html 页面:
“.app/“ 后的地址:hash 为 “#1”,histrory 为 “/1”, memory 没有
router.png

hash 模式

使用 hash 表存储路由信息

  1. <body>
  2. <a href="#1">go to 1</a>
  3. <a href="#2">go to 2</a>
  4. <a href="#3">go to 3</a>
  5. <div id="app"></div>
  6. <div id="div404" style="display: none;">not found</div>
  7. <script src="src/index.js"></script>
  8. </body>
  1. const app = document.querySelector("#app");
  2. const div1 = document.createElement("div");
  3. div1.innerHTML = "1";
  4. const div2 = document.createElement("div");
  5. div2.innerHTML = "2";
  6. const div3 = document.createElement("div");
  7. div3.innerHTML = "3";
  8. // 路由表
  9. const routeTable = {
  10. "1": div1,
  11. "2": div2,
  12. "3": div3,
  13. };
  14. function route(container) {
  15. let number = window.location.hash.substr(1);
  16. // 默认路由:如果没有指定地址,则默认为界面1
  17. number = number || 1;
  18. // 通过地址获取界面
  19. let div = routeTable[number.toString()];
  20. if (!div) { // 404 路由,如果没有找到地址,则跳转到 404
  21. div = document.querySelector("#div404");
  22. }
  23. div.style.display = "block";
  24. container.innerHTML = "";
  25. container.appendChild(div);
  26. }
  27. // 为了同时满足嵌套路由,route 传入一个挂载容器
  28. route(app);
  29. window.addEventListener("hashchange", () => {
  30. // 若 hash 变了则重新路由
  31. route(app);
  32. });

histrory 模式

需要后端将所有前端路由都渲染到同一页面

  1. <body>
  2. <a class="link" href="/1">go to 1</a>
  3. <a class="link" href="/2">go to 2</a>
  4. <a class="link" href="/3">go to 3</a>
  5. <div id="app"></div>
  6. <div id="div404" style="display: none;">not found</div>
  7. <script src="src/index.js"></script>
  8. </body>
  1. const app = document.querySelector("#app");
  2. const div1 = document.createElement("div");
  3. div1.innerHTML = "1";
  4. const div2 = document.createElement("div");
  5. div2.innerHTML = "2";
  6. const div3 = document.createElement("div");
  7. div3.innerHTML = "3";
  8. const routeTable = {
  9. "/1": div1,
  10. "/2": div2,
  11. "/3": div3,
  12. };
  13. function route(container) {
  14. let number = window.location.pathname;
  15. console.log("number: " + number);
  16. if (number === "/") {
  17. number = "/1";
  18. }
  19. // 获取界面
  20. let div = routeTable[number.toString()];
  21. if (!div) {
  22. div = document.querySelector("#div404");
  23. }
  24. div.style.display = "block";
  25. // 展示界面
  26. container.innerHTML = "";
  27. container.appendChild(div);
  28. }
  29. const allA = document.querySelectorAll("a.link");
  30. for (let a of allA) {
  31. a.addEventListener("click", e => {
  32. e.preventDefault();
  33. const href = a.getAttribute("href");
  34. window.history.pushState(null, `page ${href}`, href);
  35. // 通知
  36. onStateChange(href);
  37. });
  38. }
  39. route(app);
  40. function onStateChange() {
  41. route(app);
  42. }

memory 模式

不通过地址路由,将路由信息记录到 localStorage 中
适用于移动端等不方便或不能输入地址的地方
html 代码与 histrotry 相同

  1. const app = document.querySelector("#app");
  2. const div1 = document.createElement("div");
  3. div1.innerHTML = "1";
  4. const div2 = document.createElement("div");
  5. div2.innerHTML = "2";
  6. const div3 = document.createElement("div");
  7. div3.innerHTML = "3";
  8. const routeTable = {
  9. "/1": div1,
  10. "/2": div2,
  11. "/3": div3,
  12. };
  13. function route(container) {
  14. let number = window.localStorage.getItem("xxx");
  15. if (!number) {
  16. number = "/1";
  17. }
  18. // 获取界面
  19. let div = routeTable[number.toString()];
  20. if (!div) {
  21. div = document.querySelector("#div404");
  22. }
  23. div.style.display = "block";
  24. // 展示界面
  25. container.innerHTML = "";
  26. container.appendChild(div);
  27. }
  28. const allA = document.querySelectorAll("a.link");
  29. for (let a of allA) {
  30. a.addEventListener("click", e => {
  31. e.preventDefault();
  32. const href = a.getAttribute("href");
  33. window.localStorage.setItem("xxx", href);
  34. // 通知
  35. onStateChange(href);
  36. });
  37. }
  38. route(app);
  39. function onStateChange() {
  40. route(app);
  41. }