Fork me on GitHub

浅析使用vue-router实现前端路由的两种方式

关于vue-router

由于最近的项目中一直在使用vue,所以前端路由方案也是使用的官方路由vue-router,之前在angularJS项目中也是用过UI-router,感觉大同小异,不过很显然vue-router更友好一些。本文就以vue-router为例浅析我所理解的前端路由,具体用法和一些基本语法就不一一介绍了,官方文档说的更加清晰

关于前端路由

据我所知,在现在这些MVC和MVVM框架兴起之前,是不存在前端路由的,页面之间的跳转是由后台控制的。随着前后端分离和单页面应用(SPA)的兴起和WEB项目复杂度的增加,再加上前面这些框架的支持,慢慢前端路由也就成为了现实。单页面应用的特点就是可以在改变URL在不重新请求页面的情况下更新页面视图。

“更新视图但不重新请求页面”是前端路由的原理的核心之一,目前在浏览器环境中这一功能的实现主要有两种方式

  • 利用URL中的hash(”#”)
  • 利用History interface在 HTML5中新增的方法

下面我们就来看看vue-router是如何通过这两种方式来实现前端路由的

vue-router实现前端路由的方法和对比

使用过vue-router的都知道,在vue-router中有mode这样一个参数,这个参数的可选值有”hash”、 “history”、”abstract”

1
2
3
4
const router = new VueRouter({
mode: 'history',
routes: [...]
})

对应我们上面讲到的两种方式来说,hash就是第一种方式,history就是第二种方式,而第三种是在nodejs下的默认实现方式。

那”hash”和”history”这两种方式各有什么优劣呢?

  • 首先在vue-router中默认使用的是hash这种方式,因为这种方式虽然带个#有点丑(官方竟然都这样说),但是不存在兼容性问题
  • 而history由于底层的实现根据MDN的介绍,调用history.pushState(),所以存在浏览器兼容性问题。
  • 如果不考虑兼容性问题的话,pushState肯定比只修改hash值更加强大,因为可以设置任意同源URL
  • pushState可以设置和当前URL一模一样,这样也会把记录添加到栈中,而hash设置的新值必须和原来不一样
  • 还有,就算不考虑兼容问题的话,history模式还有一个问题,就是history模式会将URL修改的和正常请求后端的URL一样

    1
    http://oursite.com/user/id

    这样的话如果后端没有配置对应的user/id这样一个地址的话就会返回404,官方推荐的解决办法是在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。同时这么做以后,服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html 文件。为了避免这种情况,在 Vue 应用里面覆盖所有的路由情况,然后在给出一个 404 页面。(这种方案我还没实践过,有机会要实践一下)

    • 所以综合考虑来说用在一些中后台项目中的话一般直接就采用hash这种默认方式了,而前台项目的话看需求选择使用history还是hash

后记

在写这篇文章之前看了一个大神写的分析vue-router的文章,每得出一个结论之前都是截取了相应的源文件,真的是做到了 有理有据,实在佩服。我文中之所以没引用是因为实在没有通读过vue-router的源码,也还不是看的太懂,所以就不班门弄斧了,但是在看这篇文章的过程中也慢慢打消了一些对源代码的恐惧,原来源代码也没那么晦涩难懂,认真看还是能看懂大部分的,所以以后移动要多多读这样的文章,慢慢试着去看看源代码,那样得到的结论才是最有一句的,而不是人云亦云,加油!

参考文章: