$mount:把template字符串搞成真实dom的过程。关键1编译的时候碰到自定义组件怎么处理?关键2虚拟dom转换真实dom的时候碰到自定义组件又是怎么处理?本文关注的是vue处理组件的时刻,从Vue.$mount()debug进去,自上而下捋通处理组件的一个绝对流程
- 根组件
$mount()⬇ - 如果没有写render属性,则
compileToFunctions编译出render函数
- 编译会根据template字符串,
parse生成 ast 树状结构对象 generate生成render函数字符串(这个过程处理了v-if、v-for等标签从逻辑上是如何影响dom结构和数量的),最后new Function得到render函数
-
根组件
new Watcher⬇ -
updateComponent⬇众所周知的beforeMount、mounted在这个方法中先后调用 -
执行
render()得到根组件虚拟dom
- render中的_c 即h 即
createElement,当传入_c的是自定义组件的标签,会调用createComponent,为该组件准备好init方法以及构造方法,注意只是准备,不是执行,并为该组件标签生成一个vnode返回
-
_update(根组件vnode)⬇ -
patch⬇ -
createEl⬇ 虚拟dom转换为真实dom的方法
- 因为vnode是一颗树,所以会向下递归调用createEl,但要注意这里只是html标签的递归
- 所以说,vnode并不是组件树哦,充其量只是描述一个个组件页面的html标签树,因为vnode对象本身并没有向下用继续用vnode描述组件内部内容的能力
- 如果传入createEl的vnode是自定义组件,于是调用
createComponent⬇ - 这个自定义组件标记为child,然后
init⬇
child实例化 构造函数就是在前面执行render的时候准备好的child.$mount()⬇- 终于,回到梦开始的地方,现在才是真正意义上,开始了组件递归 👉
- 如果child没有写render属性,
compileToFunctions child new watcher⬇...
-
最后child完成实例化和
$mount(),才会把自己insert()插入到dom 然后继续走父组件$mount剩下的代码
ps:上面⬇是进入方法内部的意思
刚开始学习vue2,记录以上过程,旨在建立一个对Vue自上而下挂载的本质认识,并且足够精简,但不讨论细节,如有不对希望大佬勘误