从头开始学Vue-Router

2019-06-22  本文已影响0人  A郑家庆

前言

Vue-Router提出来是为了解决什么问题,跟以前写<a>标签或者重新打开一个浏览器窗口有什么不同,有什么优势,它的实现原理是什么等等带着这些问题我们来深入了解一下Vue-Router。

背景

以前我们打开页面一般都是用<a>标签或location.herf或window.open等方式,我们发现有时候每打开一个页面都会有点卡,因为我们每打开一个浏览器窗口都会重新加载所需要的资源包括公共css、js、图片等等,很多页面都加载的是同样的公共资源,这样子就会造成浏览器性能的大量消耗,并且前端重复的代码非常多,因为代码不能复用,比如头部或者底部很多html文件都要写一份,很不利于维护,特别是遇到复杂项目的时候,工作量成倍增加。为了注重用户体验(降低浏览器性能损耗)、开发大型复杂的项目(组件化,不需要重复写大量的代码)这两个主要难题的时候,单页面应用被提了出来。

单页面应用(SPA)

单页面应用是指只有一个页面的应用,在浏览器中运行期间不会重新加载页面,之后所有的交互操作都在一个页面上完成,这些都是通过vue-router切换不同的vue组件来显示不同的组件内容。公共资源(js、css等)仅需加载一次且一次全部加载,所以会有首屏问题,就是第一次打开页面有点慢,多页面应用是按需加载公共资源,所以没有首屏问题。
如图:

image.png

从上图我们可以看到Page-One、Page-Two、Page-Three共用一个Header和Footer。

多页面应用(MPA)

多页面跳转重新加载页面,所需公共资源(js、css等)会重新加载,所以很多页面都会加载相同的公共资源,造成浏览器性能的巨大浪费。
如图:


image.png

从上图我们可以看到Page-One、Page-Two、Page-Three每个页面都需要分别写一个Header和Footer造成大量代码重复。

具体对比分析:
单页面应用 多页面应用
组成 一个index.html页面和若干组件组成 多个完整页面构成
资源共用(css、js、img等) 共用,只需要在index.html页面加载 不共用,每个页面都需要加载
刷新方式 页面局部刷新或更改 整页刷新
url模式 a.com/#/pageone a.com/#/pagetwo a.com/pageone.html a.com/pagetwo.html
用户体验 页面组件的切换快,用户体验好 页面之间的切换加载缓慢,流畅度不够,用户体验比较差
转场动画 容易实现 无法实现
数据传递 容易 依赖url传参、cookie、localStorage等
搜索引擎优化(SEO) 需要单独方案、实现较为困难、不利于SEO检索,可利用服务器端渲染(SSR)优化 实现方法简易
试用范围 高要求的体验度、追求界面流畅的应用 适用于追求高度支持搜索引擎的应用
开发成本 较高,常需借助专业的框架 较低,但页面重复代码多
维护成本 相对容易 相对复杂

从上图我们可以看到单页面应用的优势和劣势:

单页面应用的好处
单页面应用的缺点

Vue-Router原理

这里的路由是SPA的路径管理器。Vue-Router是Vue.js官方的路由插件,它和Vue.js是深度集成的,适合于构建单页面应用。Vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面,是通过超链接来实现页面跳转,在Vue-Router单页面应用中,则是路径之间的切换,也就是组件的切换。Vue路由的本质就是建立起hash路由和组件之间的映射关系。
单页面应用的核心之一是更新视图而不重新请求页面,Vue-Router在实现单页面应用前端路由时,提供了两种方式:Hash模式和History模式,根据mode参数来决定采用哪一种方式,这两种方式都不会让页面重新加载。

Hash模式:

我们经常在url中看到#,这个#有两种作用,一种用来实现锚点功能,一种用来做hash路由,hash是#号后面的部分,单单改变#后的部分是不会刷新页面,不会重新加载页面,同时每一次改变#后的部分,都会在浏览器的访问历史中增加一条记录,使用后退按钮就可以回到上一个页面,Vue-Router就是利用这一点来实现前端路由。主要原理是通过监听 # 后的 URL 路径标识符的更改而触发的浏览器 的hashchange 事件,然后通过获取 location.hash 得到当前的路径标识符,再进行一些路由跳转的操作。

History模式

由于hash模式会在url中自带#,如果不想要很丑的 hash,我们可以用路由的 history 模式,只需要在配置路由规则时,加入"mode: 'history'",这种模式充分利用了html5 history interface 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器记录栈,在当前已有的 back、forward、go 基础之上,它们提供了对历史记录修改的功能。只是当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会立即向后端发送请求。

//main.js文件中
const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

当你使用 history 模式时,URL 就像正常的 url,如 http://yoursite.com/user/id,看上去就像修改了url。不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id就会返回 404,这就不好看了。所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

 export const routes = [ 
  {path: "/", name: "homeLink", component:Home}
  {path: "/register", name: "registerLink", component: Register},
  {path: "/login", name: "loginLink", component: Login},
  {path: "*", redirect: "/"}]

此处就设置如果URL输入错误或者是URL 匹配不到任何静态资源,就自动跳到到Home页面。

Vue-Router可以用来管理哈希路由、传递数据
参考文章:
路由源码:https://juejin.im/post/5cd8d609e51d456e7b372155
https://mp.weixin.qq.com/s/xVDUtqA-V3jXO_-orFDfCg/#/32434324

上一篇 下一篇

猜你喜欢

热点阅读