前端路由的两个基本条件
- 改变
url
- 页面不刷新
Hash 路由
hash
只作用在浏览器,不会在请求中发送给服务器。hash
发生变化时,浏览器并不会重新给后端发送请求加载页面。- 修改
hash
时会在浏览器留下历史记录,可以通过浏览器返回按钮回到上一个页面。 hash
发生变化时会触发hashchange
事件,在该事件中可以通过window.location.hash
获取到当前 hash 值。
在添加路由的时候添加一个对象,包括url
和跳转该地址的处理函数。hashchange 事件可以监听url
的变化。
History 路由
利用H5
的history.pushState()
和history.replaceState()
,分别可以添加和修改历史记录。它们是与 hash 一样具有修改url
的功能,之后可以通过windows
的onpopstate
事件,来监听url
的变化,进而处理该url
的处理函数。
因为History
路由改变的是浏览器的url
,因为url
改变了,此时如果手动的刷新页面,浏览器会认为是请求一个新的页面,但是新的页面是不存在的(因为url
中显示的是通过pushstate
加的记录,实际上没有对应的页面),肯定会报错的!
所以需要配合后端,在服务端做url
的重定向,就是如果找不到页面,那么就重定向到index.html
,vue
项目本身就是单页面应用,整个系统也只有一个html
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<script src="router.js"></script>
</head>
<body>
<div>
<button id="btn">点击跳转到 list</button>
<button id="detail">点击跳转到 detail</button>
</div>
<script>
var router = new Router();
router.add("/list", function () {
window.alert("/list路由被添加进来啦");
});
router.add("/detail", function () {});
router.listen();
var btn1 = document.getElementById("btn");
btn1.addEventListener("click", function (e) {
router.push("/list");
});
var btn2 = document.getElementById("detail");
btn2.addEventListener("click", function (e) {
router.push("/detail");
});
</script>
</body>
</html>
// router.js
function Router() {
this.routes = [];
/* 添加路由 */
this.add = function (re, handler) {
this.routes.push({ re, handler });
};
/* 监听 url 变化 */
this.listen = function () {
//路由切换
window.addEventListener(
"hashchange",
function (event) {
var hash = window.location.hash;
for (var i = 0; i++; i < this.routes.length) {
if (hash === this.routes[i].re) {
this.routes[i].handler.apply({});
}
}
},
false
);
};
/* 前进到一个新的url */
this.push = function (path) {
window.location.hash = path || "";
};
/* 替换成一个新的url */
this.replace = function (path) {
path = path || "";
var i = window.location.href.indexOf("#");
window.location.replace(
window.location.href.slice(0, i >= 0 ? i : 0) + "#" + path
);
};
/* 返回到上一个url */
this.back = function () {
window.history.back();
};
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ZengXPang's blog!
评论