路由基础知识小结

95 阅读2分钟

路由的一些概念

路由

路由routing)就是通过互联的网络把信息从源地址传输到目的地址的活动。

分发

路由通常根据路由表来引导分组转送。

路由表

一个存储到各个目的地的最佳路径的表。作成硬件的话,则称为路由器。

在前端的js中,我们一般将hash值和相应的标签绑定在一起

const routeTable = {
  "1": div1, //左边是hash值,右边是div
  "2": div2,
  "3": div3,
  "4": div4
};//将各个div集合到路由表,使用时直接使用路由表
默认路由和404

默认路由:没有选择的情况下,进入的默认路径

404:找不到相关路径,直接404

hash模式

思路:利用 URL 中的hash("#")来制定路径

缺点:SEO不友好,原因在于服务器收不到hash,浏览器不会将#号后面的数字发给服务器。

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <a href="#1">go to 1</a> 
    <a href="#2">go to 2</a> 
    <a href="#3">go to 3</a>
    <a href="#4">go to 4</a>
      
    <div id="app"></div>
    <div id="div404" style="display: none;">你要找的内容被狗吃了</div>

    <script src="src/index.js"></script>
  </body>
</html>

index.js

const app = document.querySelector("#app");
const div1 = document.createElement("div");
div1.innerHTML = "1";
const div2 = document.createElement("div");
div2.innerHTML = "2";
const div3 = document.createElement("div");
div3.innerHTML = "3";
const div4 = document.createElement("div");
div4.innerHTML = "4";
const routeTable = {
  "1": div1, //左边是hash值,右边是div
  "2": div2,
  "3": div3,
  "4": div4
};//将各个div集合到路由表,使用时直接使用路由表

function route(container) {
  let number = window.location.hash.substr(1);

  number = number || 1;//默认路径设置为1

  // 获取界面
  let div = routeTable[number.toString()];
  if (!div) {
    div = document.querySelector("#div404");
  } //设置404
 

  // 展示界面
  container.innerHTML = "";
  container.appendChild(div);
}

route(app);

window.addEventListener("hashchange", () => {
  console.log("hash 变了");
  route(app);
});
history模式

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

缺点:IE8一下不支持

举例:

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <a class="link" href="/1">go to 1</a> <a class="link" href="/2">go to 2</a>
    <a class="link" href="/3">go to 3</a> <a class="link" href="/4">go to 4</a>
    <div id="app"></div>

    <div id="div404" style="display: none;">你要找的内容被狗吃了</div>

    <script src="src/index.js"></script>
  </body>
</html>

index.js

const app = document.querySelector("#app");
const div1 = document.createElement("div");
div1.innerHTML = "1";
const div2 = document.createElement("div");
div2.innerHTML = "2";
const div3 = document.createElement("div");
div3.innerHTML = "3";
const div4 = document.createElement("div");
div4.innerHTML = "4";
const routeTable = {
  "/1": div1,
  "/2": div2,
  "/3": div3,
  "/4": div4
};

function route(container) {
  let number = window.location.pathname;
  console.log("number: " + number);

  if (number === "/") {
    number = "/1";
  }

  // 获取界面
  let div = routeTable[number.toString()];
  if (!div) {
    div = document.querySelector("#div404");
  }
  div.style.display = "block";

  // 展示界面
  container.innerHTML = "";
  container.appendChild(div);
}

const allA = document.querySelectorAll("a.link");

for (let a of allA) {
  a.addEventListener("click", e => {
    e.preventDefault();
    const href = a.getAttribute("href");
   window.history.pushState(null, `page ${href}`, href);
    // 通知
    onStateChange(href);
  });
}

route(app);

function onStateChange() {
  console.log("state 变了");
  route(app);
}

以上代码有hash 改编。

首先我们将html和js文件中所有的 #1.. 改成 /1..

接着对 route() 这个展示页面的函数路径的函数进行修改:

let number = window.location.pathname;

window.location.hash.substr(1) 改成 window.location.pathname

这两步使得我们点击 标签以后,不再是:

http:... /#1

而是变成:

http:... /1

也就是说,我们的number变成了从路径名获取

接下来的需求是利用 history 的相关属性,对 标签的点击事件进行修改:

const allA = document.querySelectorAll("a.link");

for (let a of allA) {
  a.addEventListener("click", e => {
    e.preventDefault();//阻止<a>标签的默认事件
    const href = a.getAttribute("href");
   window.history.pushState(null, `page ${href}`, href);
 
    onStateChange(href);   // 通知变更
  });
}

首先我们用 e.preventDefault();阻止 标签的默认跳转。

接着把 hashchange 事件改成window.history.pushState()其相当于用 history API 给地址添加了一个路径字符串

如此一来,我们点击相应的 标签就能跳转到相应的页面了。

memory 模式

memory 模式就是把 “路径” 存到 localstorage 里(用户看不见的地方)。当用户使用的时候从 localstorage 里取出来

前面两种模式都是将路径存在 url 上面。memory模式则是存在 localstorage

这种模式仅仅对单击有效,俗称单机版的路由。