VueRouter源码分析

感谢

funfish, 玩弄心里的鬼, Vue.js 技术揭秘的文章,对我的帮助

前言

vue-router的源码不算很多, 但是内容也不算少。本文谈不上逐行分析, 但是会尽量详尽的说明主流程和原理。对一些工具函数和边缘条件的处理会略过,因为我也没有逐行去了解它们,请见谅。

前置基础知识

我们在学习VueRouter源码前,先来复习下hash以及histroy相关的知识。更多细节请参考mdn文档,本节内容节选自mdn文档。

hash

onhashchange

当URL的片段标识符更改时,将触发hashchange事件 (跟在#符号后面的URL部分,包括#符号)。注意 histroy.pushState() 绝对不会触发 hashchange 事件,即使新的URL与旧的URL仅哈希不同也是如此。

histroy

pushState

pushState()需要三个参数: 一个状态对象, 一个标题(目前被忽略), 和一个URL。

  • state, 状态对象state是一个JavaScript对象,popstate事件触发时,该对象会传入回调函数
  • title, 目前所有浏览器忽略
  • url, 新的url记录

replaceState

history.replaceState()的使用与history.pushState()非常相似,区别在于replaceState()是修改了当前的历史记录项而不是新建一个。

onpopstate

调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法)。

如果当前处于激活状态的历史记录条目是由history.pushState()方法创建, 或者由history.replaceState()方法修改过的, 则popstate事件对象的state属性包含了这个历史记录条目的state对象的一个拷贝。

应用初始化

通常构建一个Vue应用的时候, 我们会使用Vue.use以插件的形式安装VueRouter。同时会在Vue的实例上挂载router的实例。

import Vue from 'vue'
import App from './App.vue'
import router from './router'Vue.config.productionTip = falselet a = new Vue({router,render: h => h(App)
}).$mount('#app')

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'Vue.use(Router)export default new Router({mode: 'history',base: process.env.BASE_URL,routes: [{path: '/',name: 'home',component: Home},{path: '/about',name: 'about',component: () => import(/* webpackChunkName: "about" */ './views/About.vue')}]
})

插件的安装

在Vue的文档中指出Vue.js 的插件应该有一个公开方法 install。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象, 我们首先查看源码中install.js的文件。

在install文件中, 我们在Vue的实例上初始化了一些私有属性

  • _routerRoot, 指向了Vue的实例
  • _router, 指向了VueRouter的实例

在Vue的prototype上初始化了一些getter

  • $router, 当前Router的实例
  • $route, 当前Router的信息

并且在全局混入了mixin, 已经全局注册了RouterView, RouterLink组件.


import View from './components/view'
import Link from './components/link'export let _Vueexport function install (Vue) {if (install.installed && _Vue === Vue) returninstall.installed = true_Vue = Vueconst isDef = v => v !== undefinedconst registerInstance = (vm, callVal) => {let i = vm.$options._parentVnodeif (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {i(vm, callVal)}}Vue.mixin({beforeCreate () {// 判断是否实例是否挂载了routerif (isDef(this.$options.router)) {this._routerRoot = thisthis._router = this.$options.routerthis._router.init(this)// _router, 劫持的是当前的路由Vue.util.defineReactive(this, '_route', this._router.history.current)} else {this._routerRoot = (this.$parent && this.$parent._routerRoot) || this}registerInstance(this, this)},destroyed () {registerInstance(this)}})Object.defineProperty(Vue.prototype, '$router', {get () { return this._routerRoot._router }})Object.defineProperty(Vue.prototype, '$route', {get () { return this._routerRoot._route }})Vue.component('RouterView', View)Vue.component('RouterLink', Link)const strats = Vue.config.optionMergeStrategiesstrats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
}

Vue.util.defineReactive, 这是Vue里面观察者劫持数据的方法,劫持_route,当_route触发setter方法的时候,则会通知到依赖的组件。而RouterView, 需要访问parent.$route所以形成了依赖(我们在后面会看到)

VueRouter源码分析相关推荐

  1. element label动态赋值_浅析 vuerouter 源码和动态路由权限分配

    背景 上月立过一个 flag,看完 vue-router 的源码,可到后面逐渐发现 vue-router 的源码并不是像很多总结的文章那么容易理解,阅读过你就会发现里面的很多地方都会有多层的函数调用关 ...

  2. vue-router 源码和动态路由权限分配

    本文首发于政采云前端团队博客:浅析 vue-router 源码和动态路由权限分配https://www.zoo.team/article/vue-router-analysis 背景 上月立过一个 f ...

  3. 浅析 vue-router 源码和动态路由权限分配

    背景 上月立过一个 flag,看完 vue-router 的源码,可到后面逐渐发现 vue-router 的源码并不是像很多总结的文章那么容易理解,阅读过你就会发现里面的很多地方都会有多层的函数调用关 ...

  4. 【vue-router源码】五、router.addRoute、router.removeRoute、router.hasRoute、router.getRoutes源码分析

    [vue-rouer源码]系列文章 [vue-router源码]一.router.install解析 [vue-router源码]二.createWebHistory.createWebHashHis ...

  5. 【vue-router源码】十二、useRoute、useRouter、useLink源码分析

    [vue-rouer源码]系列文章 [vue-router源码]一.router.install解析 [vue-router源码]二.createWebHistory.createWebHashHis ...

  6. Vue.js 源码分析(九) 基础篇 生命周期详解

    先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated   .beforeDes ...

  7. 视频教程-经典Vue从入门到案例到源码分析教程(含资料)-Vue

    经典Vue从入门到案例到源码分析教程(含资料) 张长志技术全才.擅长领域:区块链.大数据.Java等.10余年软件研发及企业培训经验,曾为多家大型企业提供企业内训如中石化,中国联通,中国移动等知名企业 ...

  8. 微前端框架 之 qiankun 从入门到源码分析

    当学习成为了习惯,知识也就变成了常识.感谢各位的 点赞.收藏和评论. 新视频和文章会第一时间在微信公众号发送,欢迎关注:李永宁lyn 文章已收录到 github,欢迎 Watch 和 Star. 简介 ...

  9. iview-admin源码分析(三):登录页面及逻辑实现

    目录 前言 正文 一.登录页面 安装 vue-router config 配置文件 1.App.vue 2.login 页面 安装 less-loader 2.1.login-form.vue 布局代 ...

最新文章

  1. Python环境的安装(Anaconda+Jupyter notebook+Pycharm)
  2. AngularJS实现产品列表(页面搜索,排序)
  3. GDCM:尝试修复损坏的J2K / DICOM的测试程序
  4. window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法
  5. WGS84经纬度坐标转化成UTM坐标
  6. 解决谷歌浏览器flash插件已被屏蔽
  7. 华为策略路由,实现双线选路上网
  8. 基于单片机仿指针显示的电子时钟设计(毕业设计资料)
  9. hdu 6638 Snowy Smile 线段树维护最大子段和
  10. 函数的傅立叶展开掐死我吧_如果看了这篇文章你还不懂傅里叶变换,那就过来掐死我吧(二)...
  11. P6974 [NEERC2015]Adjustment Office 题解
  12. Visual Studio 2010之安装Visual Studio 2010 Service Pack 1
  13. 生信漫谈如何绘制蛋白序列的二级结构可视化图
  14. DirextX 11游戏开发(1)
  15. [前后端分离][MVC模式]JavaWeb实现简单的购物网站主体功能
  16. Linux实验搭建个人网页
  17. RDD编程初级实践(期末大作业)
  18. 计算机单片机实训报告,单片机实训总结
  19. 完整~小程序canvas制作幸运抽奖转盘
  20. 【多人在线游戏架构实战-基于C++的分布式游戏编程】开篇

热门文章

  1. jQuery: 操作select option方法集合
  2. SVG 教程 (七)SVG 实例,SVG 参考手册
  3. 使用 jQuery Mobile 与 HTML5 开发 Web App (九) —— jQuery Mobile 页面与对话框
  4. Sublime Text 2插件安装及快捷键介绍
  5. Objective-C 2.0 with Cocoa Foundation --- 3,类的声明和定义
  6. 保护 WordPress 安全的10个方法
  7. sympy特点及简单使用
  8. MongoDB基本概念和常用操作(二)
  9. C++——const加深理解之const在函数后
  10. Linux less命令:查看文件内容