Vue Router 是 Vue.js 官方的路由管理器。在早期的时候html模板存在服务端,然后根据浏览器输入不同的路径,服务端会根据不同的路径渲染不同的模板出来,这样的痛点就是用户每次操作的时候都要重新刷新页面,比如说很久之前的论坛,操作一下就要跳一下,交互体验很是不好,紧接着出现了Ajax异步加载,但多页面的跳转还是有些不尽人意,所以便有了spa应用,也就是前端路由,vue-route就是一个比较火的基于前端路由的原理实现的一个插件
好, 下边我们打开控制台
//在控制台输入这句话,定义一下hashchange的回调事件 window.onhashchange=()=>{ console.log(1) }
定义好这个事件之后当我们浏览器的hash值发生变化的时候控制台就会打印一个1
我们实验一下
//假设我们定义了一个路径叫route location.hash='/route'
效果如下图
讲到这里那剩下的就很简单了,hash模式的前端路由我们只需要在hash发生改变的时候给页面的根节点上渲染出我们想要的html就可以了
首先假设我们有个div是根节点,然后他有个id叫app,我们写一个路由类让他监听hash
// 获取这个app const _EL = document.querySelector('#app'); class HashRouter { constructor(routeList) { this.routeList = routeList; window.addEventListener('hashchange', e => { }); } }
然后发生改变的时候需要重新渲染页面
//渲染方法 render(routePath) { //获取组件 let { component } = this.list.find(el => el.path == routePath); if ( !component )return //渲染 _EL.innerText = component; }
然后我们在发生改变的时候获取到当前的hash并调用渲染函数
// 这个和onhashchange 是一样的,感觉这样写会优雅一点 window.addEventListener('hashchange', e => { this.reSetRender(); }); // 渲染当前组件 reSetRender(){ let path = location.hash.slice(1)||'/' this.render(path) }
最后实现一下hash模式路由的常用api
push(routePath) { location.hash = routePath; } replace(path) { let href = window.location.href; let url = href.split('#')[0]; location.replace(`${url}#${path}`); } go(n) { history.go(n); }
到此hash模式的路由就算是简单的实现完毕了
//假装这里有一个路由数组配置 const routeList = [XXXXXX.....] const $router = new HashRouter(routeList);
注意 这个onpopstate事件并不会在你手动更改history的时候触发,他只会在浏览器本身做出动作的时候才会被触发,比如pushState(),这个方法浏览器会做出反应,但是并不会触发该事件。
history模式路由代码实现和上边hash实现大同小异,不一样的地方就是在pushState和replaceState方法中需要手动调用一下渲染函数,具体代码如下
// 构造函数里边监听popstate事件 window.addEventListener('popstate', e \=> { this.handler(); }); // api 实现 push(path) { history.pushState(null, null, path); this.reSetRender(); } replace(path) { history.replaceState(null, null, path); this.reSetRender(); } go(num) { window.history.go(num); }
history模式访问的是真实的路由地址,如果没有配置的话刷新的时候会报404
so 一个简单的路由实现完毕,喜欢的点击赞吧