你了解路由么?
路由的话可以分为前端路由和后端路由,前端路由一般来说是spa应用后端的话是一般是ssr应用
后端路由
后端路由的话又可以叫做服务端里有,因为对于服务器来说,当接收客户端发送来的HTTP请求时,会根据所请求的相应URL来找到相应的映射函数,然后执行这个函数,并将函数的返回值发送给客户端,对于简单的静态资源服务,可以认为,所有的url映射函数就是一个文件的读取操作,对于动态的资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理 等~ . 然后根据这些读取的数据,在服务器端使用相应的模板对页面进行渲染后在返回渲染完毕的页面.
前端路由
前端路由的话 路由的映射通常是进行一些dom的显示和隐藏操作
前后端路由的优缺点
后端路由的优点: 安全性好,有利于seo搜索引擎的优化,
后端路由的缺点: 会加大服务器的压力,不利于用户的体验,会造成代码冗余
前端路由的优点: 前端路由在访问一个新页面的时候仅仅是更换了一下路径,没有网络延迟 对于用户体验来说会有相当大的提升
前端路由的缺点: 使用浏览器的前进后推键时会重新发送请求,没有合理的利用缓存,同样的不利于seo搜索引擎
前端路由的几种方案
前端路由的实现方式有两种分别是hash
和history api
这里history是需要后端做对应的路由配置的
hash的实现原理
hash的实现原理就是基于location.hash来实现的 , location.hash的值就是url中#后面的内容.比如百度 设置他的location.hash="#abcsdf" 那么他的网址就是http://www.baidu.com/#abcsdf
然后我们可以使用hashchange事件来监听hash的变化.并且通过history.length能看到路由的总条数
用hash的方案实现一个路由的切换
//首先我们要有个html
<ul>
<li><a href="#luyou1">路由1</a></li>
<li><a href="#luyou2">路由2</a></li>
<li><a href="#luyou3">路由3</a></li>
</ul>
<div id="luyouid"></div>
class router {
//存贮当前路由
hashStr: String;
constructor(hash: String) {
//初始化赋值
this.hashStr = hash;
//初始化
this.watchHash();
//绑定监听改变事件,由于this被换了,必须用bind绑定
this.watch = this.watchHash.bind(this);
window.addEventListener("hashchange", this.watch);
}
//监听方法
watchHash() {
console.log();
let hash: String = window.location.hash.slice(1);
this.hashStr = hash;
console.log(hashStr);
if (hashStr) {
if (hashStr == "luyou1") {
document.querySelector("#luyouid").innerHTML = "好好学习天天向上";
} else if (hashStr == "luyou2") {
document.querySelector("#luyouid").innerHTML = "天天向上好好学习";
} else {
document.querySelector("#luyouid").innerHTML = "学习向上";
}
}
}
}
history 原理
history这个对象哎html5的时候加入了两个api分别是history.pushState()和history.repalceState()这两个 可以在不刷新的情况下 操作浏览器的历史记录,唯一不同的是,前者是新增的一个历史记录后者是直接替换当前的历史记录
api的使用
window.history.pushState(state,title,url)
//state:需要保存的数据,这个数据在触发popstate事件时,可以在event.state里获取
//title:标题,基本没用,一般传null
//url:设定新的历史纪录的url。新的url与当前url的origin必须是一样的,否则会抛出错误。url可以时绝对路径,也可以是相对路径。
//如 当前url是 https://www.baidu.com/a/,执行history.pushState(null, null, './qq/'),则变成 https://www.baidu.com/a/qq/,
//执行history.pushState(null, null, '/qq/'),则变成 https://www.baidu.com/qq/
window.history.replaceState(state,title,url)
//与pushState 基本相同,但她是修改当前历史纪录,而 pushState 是创建新的历史纪录
history的其他api
window.history.back()//后退
window.history.forward()//前进
window.history.go(1)//前进一部,-2回退两不,window.history.length可以查看当前历史堆栈中页面的数量
哪这些操作怎么执行监听呢?
每当同一个文档的浏览历史(即history)出现变化时,就会触发popState事件,只要我们监听事件即可
window.addEventListener('popstate', function(event) {
});
当然仅仅调用pushState方法或replaceState方法,并不会触发该事件,只有用户点击浏览器后退和前进按钮时,或者使用js调用back、forward、go方法时才会触发
如何监听pushState和replaceState的变化呢?
我们可以创建2个全新的事件,事件名为pushState和replaceState,我们就可以在全局监听
//创建全局事件
var _wr = function(type) {
var orig = history[type];
return function() {
var rv = orig.apply(this, arguments);
var e = new Event(type);
e.arguments = arguments;
window.dispatchEvent(e);
return rv;
};
};
//重写方法
history.pushState = _wr('pushState');
history.replaceState = _wr('replaceState');
//实现监听
window.addEventListener('replaceState', function(e) {
console.log('THEY DID IT AGAIN! replaceState 111111');
});
window.addEventListener('pushState', function(e) {
console.log('THEY DID IT AGAIN! pushState 2222222');
});