Vue Router 路由实现思路

路由包含的概念

1.路由

只要满足一对多的关系就叫分发, 分别发送到各个地方。路由就是分发请求,路由器就是分发请求的东西。

2.hash:就是#1

3.默认路由

number = number || 1 //如果number不存在就给个保底值1

4.保底路由:404路由

if(div){

  div.style.display="block"

}else{

  div=document.querySelector("#div404")

  div.style.display="block"

}

概念5:嵌套路由

需求:https://xxx/#1/3 表示要跳转到子路由1.3 接收一个参数container,表示要替换的根。要route时说一下,要route到哪个目录下,加一个参数container,表示根在哪里。

hash 模式

根据用户URL后接的hash是#x 比如http://127.0.0.1/#1以此来判断用户想去的界面,界面用div代表。#1代表界面1即Div1

条件:
任何情况下你都可以用hash做前端路由,但是SEO不友好。

缺点:SEO不友好。 服务器收不到hash,因为浏览器是不会把#之后的内容发送给服务器。所以不管你是访问https://www.baidu.com/#1还是https://www.baidu.com/#xxx对百度来说都是同一个内容,永远只展示默认路由https://www.baidu.com。根本没法收录你的内容,这就叫SEO不友好。
但也不是绝对的,google的hashbang可以让google能识别#,需要你的服务器做些配置:加!,这样google就会认为是不同的页面。例如https://www.baidu.com/#!1

<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="div1" style="display: none;">
1
</div>
<div id="div2" style="display: none;">
2
</div>
<div id="div3" style="display: none;">
3
</div>
<div id="div4" style="display: none;">
4
</div>

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

//获取用户目标地址
let number = window.location.hash.substring(1); //去掉#

let div = document.querySelector(`#div${number}`); //获取div

let app = document.querySelector("#app");
if (div) div.style.display = "block"; //渲染界面
if (app) app.appendChild(div); //展示界面

//监听hash变化
window.addEventListener("hashchange", () => {
console.log("hash changed");
const number2 = window.location.hash.substring(1); //去掉#

const div2 = document.querySelector(`#div${number2}`); //获取div

const app2 = document.querySelector("#app");
div2.style.display = "block"; //渲染界面
app2.children[0].style.display = "none";
document.body.appendChild(app2.children[0]); //清空上一次的界面
app2.appendChild(div2); //展示界面
});

路由表

自定义hash与div的关系

const div1 = document.createElement("div"); //JS创建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() {
//获取用户目标地址
let number = window.location.hash.substring(1); //去掉#
let app = document.querySelector("#app");
number = number || 1; //如果number不存在就给个保底址1

let div = routeTable[number.toString()]; //获取div
//渲染界面
if (!div) {
div = document.querySelector("#div404");
}
div.style.display = "block";
app.innerHTML = "";
app.appendChild(div); //展示界面
}
route();

//监听hash变化
window.addEventListener("hashchange", () => {
console.log("hash changed");
route();
});

history 模式

条件1.后端将所有前端路由都渲染同一个页面(不能是404)

条件2.不需要兼容IE8以下。

只要后端能实现需求:不管你请求https://www.baidu.com/#1还是https://www.baidu.com/#xxx都得到同一个页面https://www.baidu.com,而且不需要兼容IE8以下,那你就可以使用history模式。
window.location.pathname默认会有/

index.html
<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>
-----------------------
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);//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");//获取所有a标签
//遍历,每次点击时篡改它的行为:阻止所有a标签的默认动作,不要自动刷新
for (let a of allA) { 
  a.addEventListener("click", e => {
    e.preventDefault();
    const href = a.getAttribute("href");//每次点击时获取href值
    window.history.pushState(null, `page ${href}`, href);//在不刷新页面情况下变更URL
    //通知
    onStateChange(href);//把最新的路径给他
  });
}
route(app);
function onStateChange() {
  console.log("state 变了");
  route(app);
}

memory 模式

memory模式用一个对象来存储你的东西。
hash、history模式都是把数据存在URL,URL一变,页面就要变。memory是存到localStorage里。

function route(container) {
  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);
  });
}

route(app);

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

hash、history、memory三者区别
hash、history都是把路径存在url上,只不过一个是URL的哈希,一个是URL的路径。memory不用URL,前端一般放在localStorage,移动端APP放在本地数据库里面。

memory缺点是没有URL,只对单机有效,是单机版的路由,分享无效。hash、history可以记录你的信息,所以你可以分享你的URL。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容