vue router 原理

144 阅读2分钟

一.路由表

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 };

二.router

function route() {
    let number =window.location.hash.substr(1)||1;
    
    let div =routerTable[number.toString()]
    
    //如果路由表中不存在则跳转到404页面
    if (!div) {
        div = document.querySelector("#div404");
    }
    div.style.display = "block";
    //先将容器中清空
    container.innerHTML = "";
    //展示内容
    container.appendChild(div);
}

router(app)

当hash值变化就路由一次

window.addEventListener("hashchange", () => {
    route(app);
  });

三.路由嵌套

多级路由嵌套

const routeTable = {
  "1/1": div11,
  "1/2": div12,
  "1/3": div13,
  "1/4": div14,
};

四.history

hash模式,我们的请求路径自带一个# ,通过window.location.hash获取值,history模式则是自带一个/ 我们可以通过window.location.pathname来得到这个值,路由表也相应更改

const routeTable = {
  "/1": div1,
  "/2": div2,
  "/3": div3,
  "/4": div4
};

hash对SEO不友好,因为hash部分会被浏览器直接忽略,因此服务器得不到这部分数据,而history模式IE8以下浏览器不支持

使用history也有个问题那就是每次请求都会重新刷新页面因此会变得很慢,所以我们要对他进行改进

window.history.pushState(stateObj, "page 2", "bar.html");
//1. 状态对象 2. 标题 3. url

这个api可以改变referrer,它在用户发送 XMLHttpRequest 请求时在HTTP头部使用,改变state后创建的 XMLHttpRequest 对象的referrer都会被改变。因为referrer是标识创建 XMLHttpRequest 对象时 this 所代表的window对象中document的URL。

注意 pushState() 绝对不会触发 hashchange 事件

然后我们如何监听这个变化呢,答案是不同监听,直接得到路径然后重新router

五.memory

我们将上述的history模式路劲存放地址放到localStorage中会怎样呢

function route(container) {
//从localStorage中取路径,默认为1
  let number = window.localStorage.getItem("xxx");

  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.localStorage.setItem("xxx", href);
    onStateChange(href);
  });
}