在首次渲染之前,首先进行初始化,就是初始化vue的实例成员和静态成员。
初始化结束之后,调用构造函数new Vue()
在构造函数中调用了_init()方法,这个方法相当于整个vue的入口,在这个方法中最终调用了$mount()
在entry-runtime-with-compiler.js中的 m o u n t , 即 入 口 文 件 的 mount,即入口文件的 mount,即入口文件的mount,这个文件中的**$mount的核心作用是帮我们把模板编译成render函数**,但他首先会判断我们是否传入了render,如果没有传入的话,会去获取我们的template选项。如果template也没有,他会将el中的内容作为我们的模板,然后把模板编译成render函数。(render > template > el)
$mount是通过compileToFunctions()来把模板编译成render函数的,当把render函数编译好之后,会把render函数存到options.render中。
接下来会调用runtime/index.js中的 m o u n t ( ) , 在 这 个 方 法 中 首 先 会 重 新 获 取 e l , 因 为 如 果 是 运 行 时 版 本 的 话 是 不 会 执 行 这 个 入 口 的 , 在 这 个 入 口 中 获 取 了 e l 。 所 以 如 果 是 运 行 时 版 本 的 话 , 我 们 会 在 r u n t i m e / i n d e x . j s 的 mount(),在这个方法中首先会重新获取el,因为如果是运行时版本的话是不会执行这个入口的,在这个入口中获取了el。所以如果是运行时版本的话,我们会在runtime/index.js的 mount(),在这个方法中首先会重新获取el,因为如果是运行时版本的话是不会执行这个入口的,在这个入口中获取了el。所以如果是运行时版本的话,我们会在runtime/index.js的mount中重新获取el。
接下来调用mountComponent(this,el),他在instance/lifecycle.js中定义。
首先判断是否有render选项,如果没有设置render选项但是传入了模板,而且是开发环境的话就会发送一个警告。这个判断的目的是 如果我们当前使用的是运行时版本的vue,而且vue传入了render,但是我们传入了模板,那此时会发送一个警告。告诉我们运行时版本不支持编译器。
接下来触发了beforeMount生命周期钩子函数,即开始挂载之前。
接下来定义了updateComponent,此处仅仅是定义了这个函数。在这个函数中调用了_render和_update两个方法。_render方法的作用是生成虚拟DOM,_update方法的作用是将虚拟DOM转换成真实DOM,并挂载到页面上来。
接下来创建了Watcher对象,创建时传入了updateComponent函数并调用,在Watcher中会调用他的get()方法。
Watcher对象创建完毕后,触发mounted生命周期钩子函数,即挂载结束。最终返回vue实例。
Watcher中的get()方法:
当我们创建完Watcher之后会调用一次get方法,在get方法中会调用updateComponent(),在updateComponent()中会调用_render和_update两个方法。
_render():创建虚拟DOM
在render方法中调用了用户传入的render或编译生成的render。render.call是我们创建vue实例的时候传入的render。当render执行完毕之后,将最终生成的虚拟DOM(VNode)返回。
_update(vnode…):在这个方法中调用了__patch__方法,patch方法帮我们把虚拟DOM转化成真实DOM并且挂载到页面上。他会把我们生成的真实DOM挂载到vm.$el上来。