1、思考
new Vue()这个过程中究竟做了什么?过程中是如何完成数据的绑定,又是如何将数据渲染到视图的等等。
2、分析
首先找到vue的构造函数。
源码位置:/src/core/instance/index.js
options是用户传递过来的配置项,如data、methods等常用的方法。
vue构建函数调用__init方法,但在文本中并未发现此方法,但仔细可以看到文件下方定义了很多初始方法。
首先可以看到initMixin方法,发现该方法在vue原型上定义了__init方法。
源码位置:/src/core/instance/init.js
仔细阅读以上代码,我们可以得出以下结论:
在调用beforeCreate之前,数据初始化并未完成,像data、props这些属性无法访问到
到了created的时候,数据已经初始化完成,能够访问data、props这些属性,但这时候并未完成DOM的挂载,因此无法访问到dom元素。
挂载方法是调用vm.$mount方法。
initState方法是完成props/data/method/watch/method的初始化。
源码位置:/scr/core/instance/state.js
这里我们主要看初始化data的方法为initData,它与initState在同一文件下。
仔细阅读上面代码,我们可以得到以下结论:
初始化顺序:props、methods、data
data定义的时候可以选择函数形式或者对象形式(组件只能是函数形式)
数据的响应式。
上文提到的挂载方法是调用vm.$mount方法。
阅读上方代码,可以得到一下结论:
不要将根元素放到body或者 html上
可以在对象中定义template/render或者直接使用template、el表示元素选择器
最终都会解析成render函数,调用compileToFunctions,会将template解析成render函数
对template的解析步骤大致分为以下几步:
将html文档片段解析成ast描述符
将ast描述符解析成字符串
生成render函数
生成render函数,挂载到vm上后,会再次调用mount方法。
源码位置:/src/paltforms/web/runtime/index.js
调用mountComponent渲染组件
阅读上述代码,可以得到下面结论:
会触发beforeCreate钩子
定义updateComponent渲染页面视图方法
监听组件数据,一旦发生变化,触发beforeUpdate生命钩子
updateComponent方法主要执行在vue初始化时声明的render,update方法
render的主要作用是生成vnode
源码位置:/src/core/instance/render.js
_update主要功能是调用patch,将vnode转化为真实DOM,并且更新到页面中。
源码位置:/src/core/instance/lifecycle.js
3、结论
new Vue的时候会调用_init方法
定义
s
e
t
、
set、
set、get、
d
e
l
e
t
e
、
delete、
delete、watch等方法
定义
o
n
、
on、
on、off、
e
m
i
t
等事件定
义
u
p
d
a
t
e
、
emit等事件 定义_update、
emit等事件定义update、forceUpdate、$deatory生命周期
调用$mount进行页面挂载
挂载的时候主要是通过mountComponent方法
定义updateComponent更新函数
执行render生成虚拟dom
_update将虚拟DOM生成真实DOM结构,并渲染到页面中。