1.vue-router是什么?
它是一个vue.js下的路由组件。
2.路由是什么?
router,即“路由”。路由是一个网络工程里面的术语。James F.Kurose,Keith W.Ross著.陈鸣译.《计算机网络》中有讲到
路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程
在WEB开发的世界里面,路由其实指的就是控制我们在浏览器中输入的URL应该走入哪个页面中的一个组件。
3.为什么需要路由?
在最原始的ASP,以及传统的 开发中,我们在浏览器路径中输入URL,位于服务器上的WEB服务器程序(比如说Apache httpd)则会自动更加这URL,找到WEB目录下对应的文件,通过一些解析器将服务端脚本执行之后返回的HTML内容发回给浏览器,浏览器将收到的HTML渲染出来。这时WEB服务器程序(比如说Apache httpd)自己就完成了这个路由功能。
比如说wordpress的后台就是
http://www.changwei.me/wp-admin/post-new.php
直接请求对应的php脚本,该脚本执行之后返回HTML给浏览器渲染。
但是现在越来越流行框架开发了,很多PHP项目都是用框架开发的,框架都遵循单一入口原则,也就是在WEB目录下只有一个index.php文件和一些静态资源文件,其他所有业务逻辑以及框架本身的代码都写在WEB目录外面的各种文件中,所有入站请求都到达入口文件,入口文件再通过请求的各种参数来判断应该是将请求分发给WEB目录外的哪个文件(控制器)执行。我们如果有幸能够找到一些使用非常老的PHP框架开发的网站,观察他们的站内连接,各种URL上面有可能会像这种样子
http://xxx.com/index.php?module=home&controller=passport&action=login
等等,这就是该框架通过入口文件接受module,controller,action等参数来判断究竟应该把该请求分发给哪个模块,哪个控制器,哪个操作去处理。这样就可以十分神奇的实现只有一个文件就处理千千万万逻辑的方法。
到了现在WEB2.0时代,信息分享是很多用户上网的主要操作,如果你的URL足够简短美观,那么用户只需要简单的输入URL就可以访问对应的网页,而不用输入一堆module,controller,action之类的非IT行业的用户看起来不明不白的单词。同时也为了SEO(搜索引擎优化)和URL美观,因此路由便诞生了。
路由可以进一步将类似于
http://xxx.com/index.php?module=home&controller=passport&action=login
这样的URL简写成
http://xxx.com/login
这样看起来是不是美观了很多。
4.Apache自带URL重写可以达到上述目的,为什么还需要路由?

如果你会问出这个问题,你一定还没有体验过PHP的Laravel框架。
我们看一看Laravel在输出hello world的时候,用xphrof做性能测试的结果,发现路由相关的操作占据了大量执行时间,从中也可以侧面看出Laravel中路由的功能强大。
前面说了这么多,还是没讲到路由究竟好在哪?为什么不用各种WEB服务器自带的URL重写功能?
首先URL重写只是单纯的正则表达式匹配请求URL,然后将请求转发到真正的URL路径上执行,这里从高内聚低耦合的角度来看,URL重写将一个WEB程序的业务逻辑分散到了WEB服务器程序和WEB程序两个地方。并且我们从Apache服务器程序换到nginx上还需要修改配置文件,移植性降低了。另外我们有的时候需要对一组URL进行一些特殊的操作,比如说所有后台操作请求都必须验证登录操作,在传统的开发中,要么在每一个后台操作的脚本(控制器)中写一个验证操作,更加高级一点的会include一个验证脚本,但是怎么看还是不够优雅。现在有路由了,可以将一组和后台操作有关的URL都划分到一个分组中,然后绑定中间件(和java中的过滤器,拦截器很像)
5.vue-router在前端开发中能带来什么好处?
前面讲了这么多关于路由的好处,其实都指的是后端路由。也就是前后端不分离的项目中的路由。现在我们是前后端分离项目中,路由有什么用,能带来什么好处呢?
我们先看看知乎客户端
这是知乎客户端的两个页面。
我们先来看看这个需求:
有一天产品经理说需要开发一个像知乎一样的SPA,要求底部有一些按钮固定不动的底部导航栏,顶部也有一个带有返回按钮的导航栏固定不动,点击底部导航栏之后,中间部分的页面应该跳转到对应功能页面,点击顶部的返回按钮之后,应该返回到之前的页面。
如果是传统开发,你肯定第一想到的是使用css的display进行切换显示不同的vue组件(components)实现。
但是我们看到知乎底部的“我的”按钮存在一个逻辑,如果用户没有登录,那么他会跳转到登录页面,如果已经登录则显示对应页面。如果使用传统开发,那么就会显得很不优雅。
另外还要考虑一个情况,就是一般访问SPA的用户都是移动端,移动端最需要考虑的就是加载速度,并且不能耗费用户过多流量。那么就需要让用户点击这个按钮之后再加载这个组件的相关代码,以及该组件需要请求的数据,最后在渲染页面。
最后就是URL要美观漂亮,并且URL可以动态接受参数,比如说网易云音乐这个非常典型的SPA项目便使用了后端路由并且可以接受参数
http://music.163.com/#/my/m/music/playlist?id=121597667
要满足这些需求的话,在vue.js下使用vue-router是最合适不过的了。
6.vue-router都提供了什么?
1.前端路由(编程式导航 · GitBook):让页面中的部分内容可以无刷新的跳转,就像原生APP一样。
2.懒加载(懒加载 · GitBook):结合异步组件以及在组建的created钩子上触发获取数据的ajax请求(数据获取 · GitBook)可以最大化的降低加载时间,减少流量消耗。
3.重定向(重定向 和 别名 · GitBook):可以实现某些需要根据特定逻辑改变页面原本路由的需求,比如说未登录状态下访问“个人信息”时应该重定向到登录页面。
4.美化URL(HTML5 History 模式):还记得前面网易云音乐的URL吗?
http://music.163.com/#/my/m/music/playlist?id=121597667
网易云音乐网页版的URL里面几乎都带有一个#号,大家可能会疑惑,#号是URL的hash部分,并不会传递到服务端,那么#号起什么作用呢?其实前端路由器就是通过URL的hash部分来像传统的后端路由器一样判断某些请求需要交给哪个前端组件处理。
但是大家都会觉得URL里面带一个#号太丑了,要是能像传统WEB应用一样的URL多好。这个时候vue-router提供的“HTML5 History 模式”就“完美”解决了这个问题。
为什么前面的完美要加上引号呢?
请参考官方文档:
不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。
所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个index.html 页面,这个页面就是你 app 依赖的页面。
这里还要引出另一个话题,就是为什么前端路由的时候需要改变URL呢?前面提到了WEB2.0时代是一个信息分享的时代,如果用户切换到了另一个页面,但是URL仍然显示的是index.html,那么用户想要分享这个页面给他的朋友,他的朋友访问到的则只是这个SPA的首页,并不是这个分享的用户本身希望他朋友看到的页面。因此前端路由在改变页面的时候必须让URL跟着一起变。这样同时也近似完美地解决了历史上ajax导致浏览器返回前进按钮失效的问题。
5.前置操作,中间件,过滤器,拦截器(导航钩子 · GitBook)
在后端路由中都有前置操作,中间件,过滤器,拦截器等概念。前端路由也可以有的,vue-router本身较为完美的支持了这些功能,让你做前端SPA开发就像后端开发一样。在第三点提到的用户未登录重定向的判断逻辑就可以写在这里。
6.路由元信息(路由元信息 · GitBook):后端路由中可以对路由规则进行分组,比如说把所有需要登录才能访问的页面划分为一组。vue-router并没有路由规则分组功能,但是它提供了路由元信息,可以在元信息中定义一些规则,在路由钩子中再去判断这些规则,进行相应的操作。
7.滚动位置控制(滚动行为 · GitBook):相对于官方翻译的滚动行为,我更喜欢自己将他翻译为“滚动位置控制”,官方文档对于它的作用已经讲的比较通俗易懂了,大家可以参阅官方文档学习。