起源
什么是路由?路由其实就是指向一个特定处理函数的路径(后端:一个路由对应一个controller)
前端Ajax => 局部刷新 => SPA
多页应用 | 单页应用 |
---|---|
一个项目中有多个完整的的HTML文件 | 一个项目中只有一个完整的HTML页面(index.html) |
可以使用超链接、js实现页面间的跳转 | 可以使用改进后的超链接、js实现模板页面间的切换 |
传统的页面跳转是同步请求:在服务器生成响应内容时,客户端是一片空白 | 模板页面间的切换属于经典的异步请求:直到下一个模板页面来到,前一个模板页面到来,前一个模板页面才从当前DOM树上删除 |
页面跳转时,前一个DOM树无用了,需要从浏览器中全部删除,然后等待下一个DOM树的到来 | index.html到来时,浏览器创建一个DOM树。所有的请求都是xhr,到来时只需要作为一个片段挂载在当前DOM树——浏览器从始至终只有一个DOM树 |
当网速比较慢时(尤其是移动端应用中时),用户体验极为不好! | 不会出现一片惨白的情形,浏览体验好。 |
页面切换时,DOM被完整的删除,不可能有过场动画! | 页面切换的本质是DIV的轮换,可以很容易实现漂亮的过场动画。 |
SPA存在的问题: 所有的页面共享一个URL,无法区分,对爬虫、SEO等不友好
=> 前端路由出现:页面切换时改变URL,同时不请求后端刷新html页面
两种路由模式
hash
- hash值的改变不会引起页面刷新
- window.onhashchange可以监听到路由的变化
- 将hash值与页面切换处理函数一一对应
history
- HTML5引入了history.pushState() 和 history.replaceState() 方法,分别可以添加和修改历史记录条目,将使浏览器地址栏显示为新地址,但并不会导致浏览器加载页面,甚至不会检查新地址是否存在。使用 history.pushState() 可以改变referrer,它在用户发送 XMLHttpRequest 请求时在HTTP头部使用,改变state后创建的 XMLHttpRequest 对象的referrer都会被改变。因为referrer是标识创建 XMLHttpRequest 对象时 this 所代表的window对象中document的URL。History_API。pushState() 绝对不会触发 hashchange 事件,即使新的URL与旧的URL仅哈希不同也是如此。
- 调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法)。onpopstate
- pushState之后,在popstate触发时绑定页面切换处理函数
Vue-router的路由实现
项目地址:https://github.com/vuejs/vue-router
HTML5History源码实现(/src/index.js)
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
// $flow-disable-line
if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
return new Promise