最近解锁了一个拯救自我的新技能,就是学习之前,可以先观察下知识时间线,相关人物,以及其他背景等,让那些规则不再变得辣么无聊。
什么是路由?
通俗的讲就是根据不同的url展示不同页面或者内容。
路由的发展阶段?
路由的概念最开始是在后端出现的,在以前前后端不分离的时候,由后端来控制路由。
后端路由:
后端路由,又称服务器路由。服务器的静态页面内容的获取,映射函数可以看做是文件的读取操作。对于动态页面的获取,映射函数可能就是数据库读取操作,或是将数据进行处理,然后在服务端使用相应的模板渲染好页面,接着返回渲染完毕的页面。
这种方式在早期的前端开发中非常普遍,但是存在用户体验不好,服务器压力大等问题,也就给后来出现的前端路由提供了一片天地。
前端路由:
提到前端路由,便联想到单页应用,立马搜索单页应用什么时候出现的。单页应用最早由微软提出,同时推出了Knockoutjs,搜索得知KnockoutJs只是一个MVVM框架,其路由机制需要借助其他一些类库,如Asp.net接收客服端http请求的URL找到对应的映射函数,然后将函数的返回值发送给客户端。将MVVM及单页面应用发扬光大的Google推出了Angularjs。
前端路由的两种模式
目前前端的路由实现主要是两种方式,这两种方式都是基于浏览器自身的特性,两种方式分别是 hash路由 & history路由
hash路由:
hash值指的url#后面的字符串,hash值的改变只影响浏览器行为,不会导致浏览器向服务器发送请求,因此在h5的history模式出现之前,都是通过hash控制路由。
window对象提供了onhashchange事件来监听hash值的改变,一旦url中的hash值发生改变,便会触发该事件
<div id="nav"> <a href="#/page1">page1</a> <a href="#/page2">page2</a> <a href="#/page3">page3</a> </div> <div id="container"></div>
let hashValue; let container = document.getElementById('container'); window.onload = () => { checkHash()} // 初始化界面 window.addEventListener('hashchange', checkHash) // hashchange检测hash值的改变 function checkHash() { hashValue = window.location.hash container.innerHTML = hashValue === '#/page1' ? '页面一' : hashValue === '#/page2' ? '页面二' : '页面三' }
history路由:
在html5出现之前,history对象就只有简单的前进、后退、跳转等方法,HTML5标准发布h后,多了两个 API,pushState 和 replaceState,通过这两个 API 可以改变 url 地址且不会发送请求。同时还有popstate事件。通过这些就能用另一种方式来实现前端路由了。
<div id="nav"> <a href="/page1">page1</a> <a href="/page2">page2</a> <a href="/page3">page3</a> </div> <br/> <div id="container"></div>
let pathName; let container = document.getElementById('container'); window.onload = () => { init()} // 初始化界面 window.addEventListener('popstate', checkHistory) // popstate检测url的改变 function init() { checkHistory() // 拦截 <a> 标签点击事件默认行为, 点击时使用 pushState 修改url let linkList = document.querySelectorAll('a[href]') linkList.forEach(el => el.addEventListener('click', function (e) { e.preventDefault() history.pushState(null, '', el.getAttribute('href')) checkHistory() })) } function checkHistory() { pathName = window.location.pathname container.innerHTML = pathName === '/page1' ? '页面一' : pathName === '/page2' ? '页面二' : '页面三' }
前端路由两种模式各自特点:
hash路由:
低版本兼容性比较好
直接使用
微信开发最好用#,不然每次都要去计算签名(没亲自实践过)
History路由:
兼容性 >ie10
需后端配置支持