1.1 路由的模式
传统意义上,路由是由多个URL或者URL规则组成的,对服务端而言,网页的访问是无状态的,称之为服务端路由。而浏览器的History API则给予了一种实现可状态化页面的可能,因为页面的跳转(URL的改变)并不会出现页面刷新,这样一来状态就被维护在浏览器的History的内部状态储存之中。
vue-router有三种模式,history模式,hash模式,以及abstract模式。
· hash:使用URL hash值来作为路由。支持所有浏览器,包括不支持HTML5 History API的浏览器。hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件。因为hash发生变化的url都会被浏览器记录下来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来,所以又称为前端路由,成为了单页应用标配。
· history:依赖HTML5 History API和服务器配置。查看HTML5 History模式。前面的hashchange,你只能改变#后面的url片段,而history api则给了前端完全的自由。history api可以分为两大部分,切换和修改,参考MDN,切换历史状态包括back、forward、go三个方法,对应浏览器的前进,后退,跳转操作。
history.go(-2);//后退两次
history.go(2);//前进两次
history.back(); //后退
hsitory.forward(); //前进
修改历史状态包括了pushState和replaceState两个方法,这两个方法接收三个参数:stateObj,title,url
history.pushState({color:'red'}, 'red', 'red')
history.back();
setTimeout(function(){
history.forward();
},0)
window.onpopstate = function(event){
console.log(event.state)
if(event.state && event.state.color === 'red'){
document.body.style.color = 'red';
}
}
通过pushstate把页面的状态保存在state对象中,当页面的url再变回这个url时,可以通过event.state取到这个state对象,从而可以对页面状态进行还原,这里的页面状态就是页面字体颜色,其实滚动条的位置,阅读进度,组件的开关的这些页面状态都可以存储到state的里面。
· abstract:支持所有JavaScript运行环境,如Node.js服务器端。如果发现没有浏览器的API,路由会自动强制进入这个模式。
vue-router提供了2个指令标签(directive)组件来处理导航和自动渲染逻辑:
· <router-view> 渲染路径匹配到的视图组件,它还可以内嵌自己的<router-view>,根据嵌套路径渲染嵌套组件。
· <router-link> 支持用户在具有路由功能的应用中导航。
无论我们是做服务端开发还是前端开发,路由的使用都有一个明确的原则:不直接引用路由定义。这是一个很容易想到的问题,当显式引用路由定义的URL一旦产生变更,所有引用的地方都需要修改,当程序开始规模化时路由变得越来越多的时候,这种变更所带来的工作量会越来越大。所以vue-router提供了一种隐式路由引用方式,称为命名路由,通过路由的名称引用取代URL的直接引用。
1.2 History的控制
当我们在使用HTML5的History模式的时候,每次路由的改变都会被push到导航历史中保留,在某些情况下我们并不需要浏览器这样做,而是希望它能将原有的记录进行替换,那么我们就要了解<router-link>是如何通过编程方式控制路由进行导航的。首先,Vue实例内有一个$router对象,这个对象会提供三个方法,<router-link>则是用两种属性来对应这三个方法的调用:
router的方法 | 属性 | 说明 |
push() | - | 默认调用此方法 |
append() | append | 将目标URL追加的当前URL下 |
replace() | replace | 以现有目标URL替换现有的URL |
设置replace属性的话,当点击时,会调用router.replace()而不是router.push(),导航后不会留下历史记录。
<router-link :to="{name:'Home'}" replace></router-link>
设置append属性后,则在当前(相对)路径前添加基路径。例如,我们从/a导航到一个相对路径b,如果没有设置配置append,则路径为/b,如果配置了,则为a/b。