一.路由底層實(shí)現(xiàn)方式
1.利用監(jiān)聽hash變化
<body>
<a href='#/a'>a</a>
<a href='#/b'>b</a>
<script type="text/javascript">
window.addEventListener('hashchange', () => {
console.log(window.location.hash);
})
</script>
</body>
2.利用HTML5 模式的History
<body>
<a onClick="push('/a')" >a</a>
<a onClick="push('/b')" >b</a>
<script type="text/javascript">
function push(path) {
history.pushState({b: path}, null, path);
}
</script>
</body>
瀏覽器地址自動改變豫喧,并且不會帶有#號
兩種模式對比
- Hash 模式只可以更改 # 后面的內(nèi)容,History 模式可以通過 API 設(shè)置任意的同源 URL
- History 模式可以通過 API 添加任意類型的數(shù)據(jù)到歷史記錄中臭增,Hash 模式只能更改哈希值横辆,也就是字符串
- Hash 模式無需后端配置撇他,并且兼容性好。History 模式在用戶手動輸入地址或者刷新頁面的時候會發(fā)起 URL 請求,后端需要配置 1index.html 頁面用于匹配不到靜態(tài)資源的時候
二逆粹、簡易版哈希方式實(shí)現(xiàn)路由
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="author" content="">
<title>原生模擬 Vue 路由切換</title>
<style type="text/css">
.box,
#router-view {
max-width: 1000px;
margin: 50px auto;
padding: 0 20px;
}
</style>
</head>
<body>
<div class="box">
<a href="/home" class="router">主頁</a>
<a href="/mine" class="router">我的</a>
<a href="/team" class="router">組</a>
</div>
<div id="router-view"></div>
<script type="text/javascript">
function Vue(parameters) {
let vue = {};
vue.routes = parameters.routes || [];
vue.init = function() {
document.querySelectorAll(".router").forEach((item, index) => {
item.addEventListener("click", function(e) {
let event = e || window.event;
event.preventDefault();
window.location.hash = this.getAttribute("href");
console.log('lalala');
}, false);
});
window.addEventListener("hashchange", () => {
vue.routerChange();
});
vue.routerChange();
};
vue.routerChange = () => {
let nowHash = window.location.hash;
let index = vue.routes.findIndex((item, index) => {
return nowHash == ('#' + item.path);
});
if (index >= 0) {
document.querySelector("#router-view").innerHTML = vue.routes[index].component;
} else {
let defaultIndex = vue.routes.findIndex((item, index) => {
return item.path == '*';
});
if (defaultIndex >= 0) {
window.location.hash = vue.routes[defaultIndex].redirect;
}
}
};
vue.init();
}
new Vue({
routes: [{
path: '/home',
component: "<h1>主頁</h1>"
}, {
path: '/mine',
component: "<h1>我的</h1>"
}, {
path: '/team',
component: '<h1>組</h1>'
}, {
path: '*',
redirect: '/home'
}]
});
</script>
</body>
</html>