路由是什么
路由是用來(lái)分發(fā)請(qǐng)求
路由模式
hash模式,history模式景描,memory模式
1.hash模式
任何情況都能使用项郊,但seo不友好(服務(wù)器無(wú)法獲取hash)
我們創(chuàng)建一個(gè)id為app的div伴找,然后創(chuàng)建5個(gè)div芒粹,一開始讓它們display:none
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<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>
<div id="div5" style="display:none;">5</div>
<script src="src/index.js">
</script>
</body>
</html>
我們通過(guò)不同的hash兄纺,將不同的元素掛在到app上
const number = window.location.hash.substr(1);
const div = document.querySelector(`#div${number}`);
const app = document.querySelector("#app");
div.style.display = "block";
app.appendChild(div);
<a href="#1">to_1</a>
<a href="#2">to_2</a>
<a href="#3">to_3</a>
<a href="#4">to_4</a>
<a href="#5">to_5</a>
我們創(chuàng)建幾個(gè)a標(biāo)簽,使它們跳到不同的hash化漆,但是此時(shí)不能達(dá)到我們的預(yù)期估脆,需要監(jiān)聽一個(gè)hashchange的事件。
window.addEventListener("hashchange", () => {
console.log("hash changed");
number = window.location.hash.substr(1);
console.log(number);
div = document.querySelector(`#div${number}`);
console.log(div);
app = document.querySelector("#app");
div.style.display = "block";
app.appendChild(div);
});
此時(shí)即可監(jiān)聽路由的hash變化
封裝一下上面的代碼座云,同時(shí)處理下404
function route() {
let number = window.location.hash.substr(1);
number = number || 1
let div = document.querySelector(`#div${number}`);
let app = document.querySelector("#app");
if(!div) {
div = document.querySelector(`#div404`);
}
div.style.display = "block";
if(app.children.length > 0) {
app.children[0].style.display="none"
document.body.appendChild(app.children[0])
}
app.appendChild(div);
}
route()
window.addEventListener("hashchange", () => {
route()
});
2.history模式
后端將所有前端路由都渲染到同一個(gè)頁(yè)面疙赠,但I(xiàn)E8一下不支持
修改一下之前hash路由的代碼
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 routeTable = {
"/1": div1,
"/2": div2,
"/3": div3
};
function route() {
let number = window.location.pathname;
number = number || 1;
let div = routeTable[number.toString()];
let app = document.querySelector("#app");
if (!div) {
div = document.querySelector(`#div404`);
}
div.style.display = "block";
app.appendChild(div);
}
我們創(chuàng)建一個(gè)路由表來(lái)存放相應(yīng)的元素
此時(shí)我們能夠看到路由的切換,但是這樣每次都會(huì)刷新頁(yè)面
我們可以先阻止a的默認(rèn)效果朦拖,然后使用history.pushState
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 2",href)
})
}
此時(shí)就可以想修改hash一樣修改路由了圃阳,不會(huì)造成刷新頁(yè)面
function onStateChange(href) {
route()
}
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)
})
}
此時(shí)history模式就可以自由切換了
3.memory模式
路徑不通過(guò)url存儲(chǔ),保存在localStorage,sessionStorage等地方璧帝,適合運(yùn)行在非瀏覽器中(比如react native捍岳,weex)中。
缺點(diǎn):只對(duì)單機(jī)有效睬隶,不方便分享鏈接锣夹。