路由发展
以前的路由都是由后端实现的,根据url来重新载入页面。但是近年来前端页面变得越来越复杂导致服务器端压力越来越大。自然出现了解决方案,通过url的改变,在不刷新页面的情况下,修改页面内容,这就是本文将要介绍的前端路由。
路由分类
前端路由的两种实现方式:
- 利用history对象实现前端路由
- 监听window对象的hashchange事件实现前端路由,就是本文重点介绍的hash路由
hash路由
何为hash
- hash即URL中"#"字符后面的部分。
- hash值的改变不会导致页面重新加载。
- 通过window.location.hash属性获取和设置hash值。
直接进入栗子,通过代码来讲解hash路由原理。
我们要实现的效果就是点击左侧导航按钮,切换至对应的路由,并且改变内容区域显示。
也可以手动改变路由地址,然后内容区域也随之变化。
如图所示:
100行左右的代码就可以实现这样简单的效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>route demo</title>
<style>
* {padding: 0;margin: 0;}
ul li {list-style: none;text-align: center;}
.main {display: flex;height: 600px;}
.main .sidebar {width: 200px;border: 2px solid red;}
.main .sidebar ul {padding-top: 100px;}
.main .sidebar ul li {margin-bottom: 20px;cursor: pointer; }
.main .content {flex: 1;border: 2px solid green;padding: 20px;}
</style>
</head>
<body>
<div class="main">
<div class="sidebar">
<ul class="sidebar-ul">
<li class="stuManage">学生管理</li>
<li class="lesManage">课程管理</li>
<li class="claManage">班级管理</li>
</ul>
</div>
<div class="content"></div>
</div>
<script>
// 定义Route,路由对象构造函数
function Route(option) {
this.routes = option.routes;
this.init();
}
// 为Route添加原型方法
Route.prototype = {
constructor: Route,
// 初始化
init() {
// 监听window对象的hashchange事件来获取路由的变化
window.addEventListener("hashchange", (function (e) {
// e.oldURL e.newURL
// 获取改变后的hash值
var hash = location.hash.substring(1);
// 将hash跟本地保存的的路由中的path进行匹配,匹配到指定路由,就执行指定模块的代码
// 如果找不到符合条件的元素,那么route值为空
var route = this.routes.find(item => {
return item.path === hash;
});
if (route) {
route.component(hash);
}
}).bind(this));
// 注册好事件后,立即触发事件,在浏览器刷新后不会触发window的hashchange事件,所以需要手动触发
var changeEvent = new Event('hashchange');
window.dispatchEvent(changeEvent);
},
// 路由跳转
push({path}) {
if (path) {
location.hash = "#" + path;
}
}
}
// 根据路由的改变切换页面显示内容
function changePage(page) {
var contentDom = document.querySelector('.main .content');
if (page === '/' || page === '/student') {
contentDom.innerHTML = 'student module';
} else if (page === '/lesson') {
contentDom.innerHTML = 'lesson module';
} else if (page === '/class') {
contentDom.innerHTML = 'class module';
}
}
window.onload = function () {
// 调用构造函数,实例化路由对象,初始化路由配置
var router = new Route({
routes: [
{ path: "/", component: changePage },
{ path: "/student", component: changePage },
{ path: "/lesson", component: changePage },
{ path: "/class", component: changePage }
]
});
// 为导航注册点击事件切换路由
document.querySelector('.sidebar-ul').addEventListener("click", function (e) {
if (e.target.nodeName == "LI") {
var domClassName = e.target.className;
if (domClassName.indexOf('stuManage') > -1) {
router.push({ path: "/student" })
} else if (domClassName.indexOf('lesManage') > -1) {
router.push({ path: "/lesson" })
} else if (domClassName.indexOf('claManage') > -1) {
router.push({ path: "/class" })
}
}
})
}
</script>
</body>
</html>
新建一个html文件,将代码复制过去即可运行。可以尝试点击按钮切换路由,或者手动输入路由进行切换。
下面逐步解读代码,
1.首先来看,最核心的就是Route构造函数以及为Route添加原型方法。
Route构造函数中做了两步操作,1.接收参数。2.调用原型上的init初始化方法。
再来看原型上的两个方法,
- init方法:实现hash路由的核心。方法内第一步就为
window
对象的hashchange
事件添加监听,那什么时候会触发hashchange
事件呢。我在上面已经解释了什么是hash值,那么当hash
值发生改变的时候,就会触发hashchange
事件,事件对象可以拿到oldURL
和newURL
两个属性,分别代表改变前的url和改变后的url。当然也可以通过window.location.hash
直接拿到hash值(包含#)。拿到hash
值后要做的就是遍历传入的路由配置参数,如果有匹配的hash
值就执行对应的操作。 - push方法:提供给外界调用,跳转路由的方法。通过传递的参数改变url中
hash
值。
2.调用Route构造函数实例化一个route对象var router = new Route()
,参数就是我们的路由配置。配置中path
就是改变的hash值,component
就是匹配到hash值后进行的操作,也就是我们上面定义的changePage
函数。
3.在点击按钮的时候调用router.push({ path: "/student" })
就可以改变url的hash值,值改变了就触发了window的hashchange事件,也就执行了我们定义好的changePage
函数。
总结
这就是一个简单的hash路由的实现,示例不够完善,只是作为学习原理的一个参考。如有问题感谢指出。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。