function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
// 初始化入口
this._init(options)
}
// 这里是加载Vue的内部api
initMixin(Vue) // 加载this._init()
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
本文基于Vue 2.4.1,讲的是Vue执行的大致流程,不涉及具体细节
寻找构造函数
从
package.json
查看,构建项目指令npm run dev
的指令为rollup -w -c build/config.js --environment TARGET:web-full-dev
,查看build\config
在这里,找到了Vue的构建入口为
src\plateforms\web\entry-runtime-with-compiler.js
。在这里找到Vue
的引用在web\runtime\index.js
,接着找到core\index
,在这里挂载Vue的全局API,这里先不理会,继续找Vue的构造函数。最后在core\instance\index.js
找到Vue的构造函数流程入口
实例的初始化
当我们
new Vue(options)
的时候,就进入构造函数,并执行this._init(options)
进行初始化。在这里,this._init()
定义在core\instance\init
的initMinxin
下。到这里,就能发现,全局的api和属性在
core\global-api
,组件实例内部的的方法属性在core\instance
下。实例/组件的挂载流程
在执行
vm.$mount(vm.$options.el)
时,进入的是在platforms\web\entry-runtime-with-compiler.js
里的Vue.prototype.$mount
,挂载在Vue的原型上。在这里有段代码
这个mount在
platforms\web\runtime\index.js
上,在这里为了挂载实例方法,把$mount
作为缓存在了mount
上,以便以下面的调用模板编译和render函数执行
接下来的,是编译模板。这里只讲个生成render函数的流程。
在这里举个例子,就是
<App/>
,其他道理都相同,就是生成render函数。这个render函数
在Vue官网里有详细说明,通过render函数
可以生成Vnode就是Virtual Dom
,进而渲染domVue获取
<App />
字符串 --> 判断是否能够new Function
--> 拼接render生成字符串render:"with(this){return _c('App')}"
--> 通过new Function(code)
生成真实render函数并挂载到options
上Wactcher 观察者
在Vue2.0中,采用了跟React一样的
Virtual Dom
技术,对比虚拟与真实dom的区别,做到最小化操作dom,render函数就是为了生成Vnode
的。作为数据驱动的mvvm框架,Vue采用的是数据劫持+发布订阅的模式
,为data/computed/props
等进行了数据绑定,实现了数据的响应式响应式,而作为Vue的组件/实例
,也拥有一个观察者。看到core\instance\lifecycle
接下来看
core\observer\watcher.js
。这个是watcher构造函数的入口。到这里,watcher的初始化就完成了。当Vue以及其组件进行数据更新的时候,会通过数据的
setter
,去通知Watcher
调用渲染,通过virtual dom
实现dom的更新。后面是Vdom的生成patch/diff/update
过程Virtual Dom 大致流程以及组件渲染
先是执行
render函数
,看到core\instance\render.js
看到
core\instance\lifecycle.js
执行到
__pathch__
,后面就是virtual dom
的diff
和patch
的过程,在这里不会深入探讨,但是要完成整个流程,组件还需要去递归,递归的如果就在patch中。VueComponent 组件初始化
VueComponent
是组件的构造函数,实质上是继承了Vue
的一个子类。在编译完的
Vnode
如果是组件,都会有一个_Ctor
属性,如果我们通过webpack
,import 进来的一整个组件配置,也有这么个属性。这个属性存放的就是VueComponent
构造函数。当然这个函数是在编译的时候进行加工过的,把一些属性,例如data
computed
等的属性进行了初始化等。 看到core\vdom\create-component.js
结语
至此为止,整个Vue的创建流程就结束了。在这里,忽略了
模板编译
、Virtual Dom
和双向绑定原理
,因为这三个篇幅非常长,日后会单独拿出来写。下面这图是网上的原理图,整个的流程大概是这样了。