router
什么是router
router是伴随spa单页面应用产生的一种页面挑战实现方案,在此之前页面的跳转是通过服务器端进行控制的。 传统的页面跳转: 通过前端向后台发送请求,后端通过渲染引擎的模板,数据嵌入模板,然后返回完整的html页面,实现方式有a标签的跳转,form表单提交,js动态调用window.href h5中的historyd的go forward back。 spa页面跳转: 通过浏览器的劫持 来进行页面的跳转,以及对于数据的请求,spa实现拦截有两种方式hash和history
hash模式
运用hashchange事件的方式进行地址栏的拦截 对应的不同hash则访问的不同页面
class CreateRoute{
constructor(){
this.routes={}
this.refresh=this.refresh.bind(this)
//初级进来刷新
window.addEventListener('load', this.refresh);
//监听hash的改变
window.addEventListener('hashchange',this.refresh)
}
route(path,callback){
this.routes[path]=callback || function(){}
}
refresh(){
const href=`/${window.location.hash.slice(1)}`
console.log(href,this.routes)
this.routes[href]()
}
}
const Route=new CreateRoute()
Route.route('/about', () => changeText("关于我们页面"));
Route.route('/user', () => changeText("用户列表页"));
Route.route('/', () => changeText("首页"));
function changeText(arg) {
document.getElementById('context').innerHTML = arg;
}
history
利用pushState和replaceState两种方法操作地址栏 不会发送请求的现象,地址栏不会进行刷新的方式去实现路由的跳转,但是前进和后端会触发popstate的事件
class createRouter{
constructor(){
this.routers={}
this.currentPath=''
this.handlePopState=this.handlePopState.bind(this)
this._init=this._init.bind(this)
window.addEventListener('popstate',this.handlePopState)
window.addEventListener('load',this._init(this.currentPath))
}
_init(path){
console.log(path,this.routers)
window.history.replaceState({path},null,path)
const cb = this.routers[path]
if(cb){
cb()
}
}
go(path){
this.currentPath=path
//入栈
window.history.pushState({path},null,path)
//调用回调
const cb = this.routers[path]
if(cb){
cb()
}
}
handlePopState(e){
const path=e.state&&e.state.path
this.routers&&this.routers[path]()
}
route(path,callback){
this.routers[path]=callback
}
}
const Route = new createRouter()
Route.route('./about', () => changeText("关于我们页面"));
Route.route('./user', () => changeText("用户列表页"));
Route.route('./', () => changeText("首页"));
function changeText(arg) {
document.getElementById('context').innerHTML = arg;
}
container.addEventListener('click' , e => {
if(e.target.tagName === 'A') {
e.preventDefault();
Route.go(e.target.getAttribute('href'))
}
})
hash和history路由的区别
相同点:hash和history都是基于spa应用实现的前端页面切换方式.页面的控制跳转都发生在前端。 区别: 1.hash地址栏中带有# history地址栏则没有 2.hash不利于seo或者ssr 3.hash不需要服务器端的支持,自身就可以完成页面的跳转和加载,history需要服务端的支持,需要服务端配置首页 然后首页根据路劲再进行跳转,配置404页面的重定向index.html页面 然后走路由 (刷新的时候地址栏发送的请求不是真是存在的请求,会出现404 因此服务端需要返回index.html 再index.html 走路由配置获取对应的页面)