vue2源码框架和流程分析
vue整体框架和主要流程分析
之前对看过比较多关于vue源码的文章,但是对于整体框架和流程还是有些模糊,最后用chrome debug对vue的源码进行查看整理出这篇文章。。。。
本文对vue的整体框架和整体流程进行简要的分析,不对某些具体的细节进行分析,所有需要对vue有初步的认识,包括对Object.defineProperty、虚拟DOM有一定了解,本文不会对Object.defineProperty、虚拟DOM的原理和细节进行分析。
vue大体可以分两个部分:
1.采用Object.defineProperty进行数据的双向绑定;
2.采用虚拟DOM技术进行视图渲染;
vue入口
vue构造函数调用了this._init(options)方法,这个方法在initMixin中,如上图所示,进入initMixin
initMixin主要完成数据的初始化和视图的初始化:
1.数据初始化主要是数据的observe,在上图的initState中进行;
2.视图的初始化在vm.$mount(vm.$options.el),其中vm为Vue的实例,watcher的设置也是在vm.$mount(vm.$options.el)中完成的;
我们可以看到这里定义了beforeCreated和created这两个钩子函数。
数据初始化
接着上面我们看看数据初始化都做了什么,进入initState
这里我们主要对数据进行操作的是initData,传入的是vm,我们来具体看看initData:
我们先忽略前面的一些逻辑判断,主要看两个地方:
1.数据代理,主要是将_data的数据代理到vm上,这样的话可以直接对vm上的数据进行修改;
2.数据observe,传入data;
我们先看看vue怎么对数据进行observe的,进入observe
在observe里返回的是ob,也就是Observer类的实例,我们看看Observer类是怎么定义的,进入Observer类
如上图在对data进行observe时对数组进行了特殊的处理,这块我们先不看,先看一般情况下的处理,即调用this.walk(value)
walk主要对data的属性进行遍历,进入defineReactive
可以看到Object.defineProperty是在这里对属性设置get和set的,其中get主要进行依赖收集,其实就是在收集视图渲染的watcher,后面会提到,set主要是数据更新时进行视图的更新
至此,数据的初始化就完成了,从上面的分析来看,数据的初始化主要的工作就是对数据进行observe。
视图挂载
接着上面,在vue入口那里,我们知道视图的挂载主要是调用了vm.$mount(vm.$options.el)
如图,所以我们进入vm.$mount,看看里面都干了啥,在源码里面有两处地方涉及到$mount
这是第一处,就是return mountComponent
这是第二处,上面两个图是一起的,屏幕大小有限,所以截了两个图。。。
咱们看看第二处,里面做了一个处理,就是将template编译成render函数,在vue的教程里有render函数的使用,这里我们可以看出我们在组件里定义render函数会比定义template快,因为在定义template的组件挂载时多了一步将template编译成render函数;
第二处的return 还是调用了第一处,所以我们看看第一处调用的mountComponent方法,进入mountComponent
上面两个图是一起的,屏幕大小有限,所以截了两个图。。。
这里我们可以看到定义了两个钩子beforeMount和mount,中间调用了watcher,我们看一下这里watcher的定义,这里标注的不太好,挡住了。。。我们看看watcher的这行代码:
vm._watcher=new Watcher(vm,updateComponent,noop)
我们可以看到Watcher类主要传入了vm,updateComponent,noop三个参数,其中updateComponent的主要作用是将虚拟DOM转化为真实的DOM并进行挂载,具体的细节下面在讨论,我们下面看看Watcher类是怎么定义的,进入Watcher
这里我们注意两个地方,一个是this.getter的定义,这里就是上面传进来的updateComponent,还有就是执行this.get(),我们进入这个get方法
这里我们看到首先收集的依赖是当前watcher实例,然后调用getter方法也就是updateComponent方法,之前我们对updateComponent方法的作用进行了简单的说明,这里我们具体看看updateComponent都干了啥,进入updateComponent:
这里调用了vm._update方法,其中传入的参数有vm._render(),_render函数主要的作用是产生虚拟DOM,进入_update
这里主要是将虚拟DOM转化为真实DOM并进行挂载,分两种情况,分别是有旧的虚拟DOM和无旧的虚拟DOM,对应初始化时调用还是数据更新时调用,这里定义了一个钩子beforeUpdate
到这里,视图的初始化和挂载也结束了,下面看看数据变化时视图是如何更新的
数据变化时视图更新过程
接着上面我们看看数据变化时视图是怎么变化的,在数据初始化的时候,我们知道数据变化时将触发set方法,如下图:
上图可以看出,set最后调用了dep.notify,进入notify
如上图,notify主要将收集的依赖,也就是收集的所有watcher,调用所有watcher的update方法,我们看看watcher的updata方法干了啥
这里就是调用了queueWatcher,进入queueWatcher
这里采用队列异步更新,就是讲=将watcher push进队列queue中,然后执行nextTick方法,进入nextTick
上面两个图是一起的,屏幕大小有限,所以截了两个图。。。
这个部分有点难看,cb为传入的flushSchedulerQueue函数,执行timerFunc,将nextTickHander加入异步队列,执行nextTickHander,执行cb,既执行flushSchedulerQueue,进入flushSchedulerQueue
上面两个图是一起的,屏幕大小有限,所以截了两个图。。。
主要看watcher.run(),进入watcher.run
执行了this.get(),即进入前面数据渲染和挂载的地方
到这里,vue整个的执行流程基本就结束了。
vue流程图
盗用一下vue官网关于vue生命周期的图,对照之前的内容梳理一下:
对照上面的分析基本上可以找到各个钩子函数的位置,下面那个销毁的我就没用做分析了。。。
大家有兴趣的话可以关注一下我的博客
本文转载于:猿2048➪https://www.mk2048.com/blog/blog.php?id=h1cj1kihjaa
vue2源码框架和流程分析的更多相关文章
- Netty 源码学习——客户端流程分析
Netty 源码学习--客户端流程分析 友情提醒: 需要观看者具备一些 NIO 的知识,否则看起来有的地方可能会不明白. 使用版本依赖 <dependency> <groupId&g ...
- Chromium源码--网络请求流程分析
转载请注明出处:http://www.cnblogs.com/fangkm/p/3784660.html 本文探讨一下chromium中加载URL的流程,具体来说是从地址栏输入URL地址到通过URLR ...
- boost.asio源码剖析(三) ---- 流程分析
* 常见流程分析之一(Tcp异步连接) 我们用一个简单的demo分析Tcp异步连接的流程: #include <iostream> #include <boost/asio.hpp& ...
- Android4.0源码Launcher启动流程分析【android源码Launcher系列一】
最近研究ICS4.0的Launcher,发现4.0和2.3有稍微点区别,但是区别不是特别大,所以我就先整理一下Launcher启动的大致流程. Launcher其实是贯彻于手机的整个系统的,时时刻刻都 ...
- Vue2源码分析-逻辑梳理
很久之前就看完vue1,但是太懒就一直没写博客,这次打算抽下懒筋先把自己看过了记录下来,否则等全部看完,估计又没下文了 看源码总需要抱着一个目的,否则就很难坚持下去,我并没做过vue的项目,我几乎很少 ...
- Okhttp3源码解析(3)-Call分析(整体流程)
### 前言 前面我们讲了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析]( ...
- Spring mvc之源码 handlerMapping和handlerAdapter分析
Spring mvc之源码 handlerMapping和handlerAdapter分析 本篇并不是具体分析Spring mvc,所以好多细节都是一笔带过,主要是带大家梳理一下整个Spring mv ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/12/es-code03/ 前提 上篇文章写完了 ES 流程启动的一部分,main 方法都入 ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(上)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/11/es-code02/ 前提 上篇文章写了 ElasticSearch 源码解析 -- ...
随机推荐
- Navicat15激活(仅供学习使用,严禁任何商业用途)
Navicat15利用注册机破解的方法 需求 Navicat15下载及安装 也可以联系作者获取Navicat15及工具,仅供学习使用,严禁各种用于商业活动 1.打开搜索引擎,查找Navicat15,然 ...
- SpringBoot连接Redis (Sentinel模式&Cluster模式)
一.引入pom <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 【C语言】关于单片机中断详解
什么是中断?就是打断当前要做的事,转而去执行别的事情.比如小七我现在正在电脑前写帖子,突然老妈叫我帮她下楼拿点东西,于是我就收到了老妈给我的一个中断(可以叫做外部中断),当我去拿东西时,突然尿急(内部 ...
- SQL从零到迅速精通【实用函数(2)】
1.对查询结果进行排序 查询stu_info表中所有学生信息,并按照成绩由高到底进行排序,输入语句如下. SELECT * FROM stu_info ORDER BY s_score DESC; ...
- Java入土---Java基础(一)
注释,标识符,关键字 注释类似于我们的随手记,并且不会被执行,是写给我们自己看的,书写注释是一个非常好的习惯 重点来了,Java中注释有三种:单行注释,多行注释,文档注释 单行注释 "//& ...
- CF549G题解
变菜了,一年前做这种题10min出结论,现在对着样例胡半天都没结果 首先考虑从判断无解入手. 定义两个位置 \((i,j)\),若 \(a[i]=a[j]+(j-i)\),则 \(i\) 和 \(j\ ...
- vue项目部署到阿里云服务器(windows),Nginx代理!
项目构成: 前端:vue+vant-ui, 数据库:mysql, 后端:node.js 部署方式:nginx代理: 一,首先要拥有自己的服务器,阿里,腾讯都可以,我用的是阿里的: 如果只是做个人项目的 ...
- JavaWeb 05_JDBC入门及连接MySQL
一.概念 *概念: Java DataBase Connectivity Java数据库连接, Java语言操作数据库* JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数 ...
- pip国内镜像,提升下载速度和安装成功率
对于Python开发用户来讲,PIP安装软件包是家常便饭.但国外的源下载速度实在太慢,浪费时间.而且经常出现下载后安装出错问题.所以把PIP安装源替换成国内镜像,可以大幅提升下载速度,还可以提高安装成 ...
- 4月11日 python学习总结 对象与类
1.类的定义 #类的定义 class 类名: 属性='xxx' def __init__(self): self.name='enon' self.age=18 def other_func: pas ...