Vue-router路由原理

目前实现路由的方式有两中,vue通过参数mode来设置,默认是hash模式。

  1. 利用URL中的hash(‘#’)来实现
  2. 利用History interface在HTML5中新增的方法

history对应的是HTML5History对象,hash对应的是HashHistory对象,abstract对应的是AbstractHistory对象。在初始化对应的history之前,会对mode做一些校验:若浏览器不支持HTML5History方式(通过supportsPushState遍历判断),则mode设为hash,若不是在浏览器环境下运行,则mode设为abstract

VueRouter类中的onReady(),push()等方法只是一个代理,实际是调用的具体history对象的对应方法,在init()方法中初始化时,也是根据history对象具体的类别执行不同操作

HashHistory

Hash(‘#’)符号的本来作用是加在URL指示网页中的位置,#本身以及它后面的字符称之为hash,通过window.location.hash属性来获取

Hash虽然出现在url中,但不会被包括在http请求中,它是用来指导浏览器动作的,对服务端完全无用,因此改变hash不会重新加载页面,如果是手动在url添加hash,这时可以为hash的改变添加监听事件

Window.addEventListener(‘hashchange’,funcRef,false)

每一次改变hash(window.location.hash)都会在浏览器访问历史中增加一个记录

执行vue里的push()方法最主要的是对window的hash进行直接赋值

Window.location.hash = route.fullPath

$router.push()  -> HashHistory.push()  -> History.transitionTo()  -> History.updateRoute() -> vm.render()

HashHistory.replace()

Replace()方法与push()方法不同之处在于,它并不是将新路由添加到浏览器访问历史栈顶,而是替换掉当前的路由,背后它实际上是调用window.location.replace方法将路由进行替换

监听地址栏

VueRouter.push()和VueRouter.replace()是可以在vue组件的逻辑代码中直接调用的,除此之外在浏览器中,用户还可以手动在浏览器地址栏中输入url,因此还需要监听浏览器地址栏中路由的变化,并具有与通过代码调用的相同响应行为,在History中通过setupListeners监听hashchange实现:

Window.addEventListener(‘hashchange’,function () {}),当在浏览器地址栏直接输入路由相当于代码调用了replace()方法

HTML5History

History interface是浏览器历史记录栈提供的接口,back(),forward(),go()等方法,HTML5提供了pushState(),replateState()这两个方法

Window.history.pushState(stateObject,title,url)

Window.history.replateState(stateObject,title,url)

stateObject:当浏览器跳转到新的状态时,将触发popState事件,该事件将携带这个stateObject参数的副本

title:所添加记录的标题

url:所添加记录的url

这两个方法有个共同特点:当调用他们修改浏览器历史栈后,虽然当前url改变了,但浏览器不会立即发送请求该url,这就为单页应用前端路由,更新视图但不重新请求页面提供了基础

History与hash模式基本类似,只不过将对window.location.hash()直接进行赋值window.location.replate()改为调用了window.location.history.pushState()和window.location.replateState()方法,而HTML5History中添加对修改浏览器地址栏url的监听popstate是直接在构造函数中执行的

Window.addEventListeners(‘popstate’,e => {// 执行相应的功能})

HTML5History需要浏览器的支持,vue是通过supportPushState()来检查

除这两中模式外,vue-router还未非浏览器环境准备了一个abstract模式,原理是用一个数组stack模拟除浏览器历史记录栈的功能

两中模式比较

调用history.pushState()相比直接修改hash主要有以下优势:

  1. pushState设置的新url可以是与当前url同源的任意url,而hash只可修改#后面的部分,故可设置与当前同文档的url
  2. pushState设置的新url可以与当前url一模一样,这样也会把记录添加到栈中,而hash设置的新的值必须与原来不一样才会触发记录添加到栈中
  3. pushState通过stateObject可以添加任意类型的数据记录中,而hash只可添加短字符串
  4. pushState可额外设置title属性供后续使用

history模式问题

对于单页面应用来说,理想的使用场景是仅仅在进入用用时加载index’.html,后续在网络操作通过ajax完成,不会根据url重新请求页面,但是如果用户直接在地址栏中输入并回车,浏览器重启重新加载等特殊情况

Hash模式仅仅改变hash部分的内容,而hash部分是不会包含在http请求中的,就是#以及后面的是不会包含在请求当中的

http://baidu.com/#user/id      //如请求,只会发送http://baidu.com

所以hash模式下遇到根据url请求页面不会有问题

而history模式则将url修改的就和政策请求后端的url一样,history不带#。http://baidu.com/user/id

如果这种向后端发送请求的话,后端没有配置对应/user/id的路由处理,会返回404错误

官方推荐的解决方法是在服务端增加一个覆盖所有情况的候选资源:如果url匹配不到任何静态资源,则应该返回同一个index.html页面,这个页面就是你app依赖的页面。同时这么做以后,服务器就不再返回404错误页面,因为对于所有路径都会返回index.html文件。为了避免这种情况,在vue应用里面覆盖所有的路由情况,然后再给出一个404页面。或者如果是用node.js做后台,可以使用服务端的路由来匹配url,当没有匹配到路由的时候返回404,从而实现fallback

vue-router路由原理的更多相关文章

  1. 「进阶篇」Vue Router 核心原理解析

    前言 此篇为进阶篇,希望读者有 Vue.js,Vue Router 的使用经验,并对 Vue.js 核心原理有简单了解: 不会大篇幅手撕源码,会贴最核心的源码,对应的官方仓库源码地址会放到超上,可以配 ...

  2. 前端MVC Vue2学习总结(八)——Vue Router路由、Vuex状态管理、Element-UI

    一.Vue Router路由 二.Vuex状态管理 三.Element-UI Element-UI是饿了么前端团队推出的一款基于Vue.js 2.0 的桌面端UI框架,手机端有对应框架是 Mint U ...

  3. Vue Router 路由实现原理

    一.概念 通过改变 URL,在不重新请求页面的情况下,更新页面视图. 二.实现方式 更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有2种方式: 1.Hash  ...

  4. 04 Vue Router路由管理器

    路由的基本概念与原理 Vue Router Vue Router (官网: https://router.vuejs.org/zh/)是Vue.js 官方的路由管理器. 它和vue.js的核心深度集成 ...

  5. Vue系列:Vue Router 路由梳理

    Vue Router 是 Vue.js 官方的路由管理器.它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌.包含的功能有: 嵌套的路由/视图表 模块化的.基于组件的路由配置 路由参数. ...

  6. Vue Router路由管理器介绍

    参考博客:https://www.cnblogs.com/avon/p/5943008.html 安装介绍:Vue Router 版本说明 对于 TypeScript 用户来说,vue-router@ ...

  7. Vue Router 路由守卫:完整的导航解析流程

    完整的导航解析流程 1 导航被触发. 2 在失活的组件里调用离开守卫. 3 调用全局的 beforeEach 守卫. 4 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+). ...

  8. Vue Router路由守卫妙用:异步获取数据成功后再进行路由跳转并传递数据,失败则不进行跳转

    问题引入 试想这样一个业务场景: 在用户输入数据,点击提交按钮后,这时发起了ajax请求,如果请求成功, 则跳转到详情页面并展示详情数据,失败则不跳转到详情页面,只是在当前页面给出错误消息. 难点所在 ...

  9. Vue - Router 路由

    路由的注册 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  10. vue router路由(三)

    当环境搭建及Vue语法与指令都有所了解,该说下router. build目录是打包配置文件 (不建议动) config是vue项目基本配置文件 dist是构建后文件 js 手动创建 (根据需要) no ...

随机推荐

  1. underscore.js源码解析(五)—— 完结篇

    最近公司各种上线,所以回家略感疲惫就懒得写了,这次我准备把剩下的所有方法全部分析完,可能篇幅过长...那么废话不多说让我们进入正题. 没看过前几篇的可以猛戳这里: underscore.js源码解析( ...

  2. SSD/Memory技术学习拼图

    "打酱油"解读SLC缓存新技术[http://www.pceva.com.cn/article/3612-1.html] 固态硬盘主控将消亡?未来高性能固态硬盘长这样[http:/ ...

  3. IOC 依赖注入 Unity

    http://kb.cnblogs.com/page/115333/ http://www.bianceng.cn/Programming/net/201007/18255.htm http://bl ...

  4. Markdown语法实践

    Markdown语法实践 Markdown基本语法 1.标题 # 一级标题 ## 二级标题 ### 三级标题 eg: 一级标题 二级标题 三级标题 2.链接 标准: [Title](URL) 实例: ...

  5. pro9笔记

  6. 第二周:PSP&进度条

    PSP: 一.词频统计改进 1.表格:     C类型 C内容 S开始时间 E结束时间 I时间间隔 T净时间(mins) 预计花费时间(hrs) 学习 <构建之法>.Java 8:46 1 ...

  7. 5th 各组作品alpha发布体会

    1.  俄罗斯方块   武志远 可以进行游戏,界面很友好,游戏运行也很流畅,并找到两名同学现场体验,游戏完成度很好. 2.  连连看游戏  张金生 可以进行游戏,实现了背景音乐播放等附加功能,界面清晰 ...

  8. 【BioCode】Elm格式中提取位点信息

    说明: ①Elm格式: PLMD ID    Uniprot Accession    Position     Type     Sequence   Species    PMIDsPlMD编号 ...

  9. python编码iso-8859-9编码问题

    (2018-10-15) 路 2018骞�10鏈�16鏃�8:30鈥斺€�11:00锛屽湪鍏垽涓€搴叕寮€瀹$悊锛氬啀瀹$敵璇�.. (2018-10-15) 路 2018骞�10鏈�16鏃�8: ...

  10. Java Map获取key和value 以及String字符串转List方法

    一.问题描述 这里描述两个问题: 1.Java Map获取key和value的方法: 2.String字符串转List的方法: 二.解决方法 1.Java Map获取key和value的方法   2. ...