请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

笔记:整个组件patch流程图及总结

这两节好难啊,大半天画了下深度遍历的整个流程图,再以视频中例子总结下整个组件patch的流程。

  1. 从vm._render函数开始,本质是执行createElement的过程,其中tag为App组件导出的对象,所以执行createComponent,传入tag
  2. createComponent过程对tag进行extend处理,返回组件构造器,给data注册hooks (后面用来组件实例化),创建组件vnode,传入data, 使用componentOptions来保存构造器,tag等等,返回App组件vnode
  3. 回到_render函数, 给App组件vode设置parent属性,此时是undefined,再执行vm._update方法
  4. vue实例绑定 _vnode 属性,指向App组件vnode(占位vnode),执行vm._patch, vnode为组件App vnode
  5. Vue实例patch, 此处其实是进入了createComponent,执行 组件 vnode 的 init hook
  6. init hook中, 组件vnode实例化,执行构造器的init方法,本质是vm._init, 只是vm指向组件实例
  7. 组件实例_init 过程, 执行initInternalComponent ,初始化组件实例的$options,parent指向 vue实例,_parentNode指向组件vnode
  8. 组件实例初始化生命周期,$parent 指向 vue实例,且 添加自身到 vue实例 children,完成父子关系绑定
  9. 组件实例化完成,实例保存在组件vnode的componentInstance,组件实例执行$mount 挂载
  10. 由于vue-loader编译完成已经有了render函数,执行 _render过程,创建组件实例vnode(渲染vnode)
  11. _render过程, vm.vnode=vm.vnode = vm.vnode=vm.options._parentNode ,将占位vnode保存在 组件实例vm的$vnode
  12. 其实组件实例的render函数中,tag为App组件的根节点div,这里直接创建普通节点vnode
  13. 执行组件实例 _update , vm._vnode = vnode 将渲染vnode保存在 _vnode属性,执行组件实例 _patch
  14. 普通节点,直接进入createElm 过程,创建真实dom保存到渲染vnode的elm,创建子节点,递归执行createElm
  15. 其中遇到helloworld组件又会执行createComponent,创建helloworld组件的实例,又回到了步骤5,由于helloworld中只有普通节点,patch的结果是在helloworld组件的渲染vnode中绑定了helloworld组件的真实dom(根节点和children),在init hook 完成时,会在app组件根节点下插入 helloworld 根节点dom
  16. app组件渲染vnode patch 完成,返回 vnode.elm
  17. app组件实例KaTeX parse error: Expected 'EOF', got ',' at position 16: el = vnode.elm,̲ app组件占位vnode i…el 挂载到 组件vnode的elm下
  18. 此时将 占位vnode的elm插入到 body 中, 此时视图渲染出来了,执行后面的逻辑,删除旧的div#app节点,Vue实例的patch过程完成,vm.$el = vnode.elm, 整体流程完成

其实就是深度递归的一个挂载过程: 从最外层Vue实例,再到App组件实例,再到helloworld组件实例,helloworld实例内部DOM节点创建完成后,helloworld组件就完成了,然后就是将helloworld 的根节点挂载到 App组件根节点,App组件根节点挂载完成后,就插入到body节点下,然后移除原来的div#app。的确需要注意老师一开始提到的占位vnode和渲染vnode。分别是用$vnode 和 _vnode保存的。 另外 activeInstance 表示当前正在init的实例,可能是vue实例,也可能是组件实例,会在创建组件实例时注册到后面的组件实例的 $parent, 形成实例间的父子关系
图片描述

正在回答 回答被采纳积分+3

1回答

ustbhuangyi 2020-12-20 23:44:21

分析的很不错,也很用心,为你点赞,在 Vue2 中,$vonde 和 _vnode 的命名不好,没有语义化,这点 Vue3 就做的不错,也建议你去看看我的 Vue3 源码解析课程,组件分析这块,顺便可以和 Vue2 做个对比。

2 回复 有任何疑惑可以回复我~
  • 提问者 慕粉4283821 #1
    谢谢老师~
    回复 有任何疑惑可以回复我~ 2020-12-21 00:48:14
  • 第四条  _vnode是渲染vnode  不是 占位符vnode  ,$vnode才是占位符vnode
    回复 有任何疑惑可以回复我~ 2021-03-07 22:38:58
  • syy138 #3
    老师,vue3解析课程是笔记吗?还是视频?
    回复 有任何疑惑可以回复我~ 2022-01-19 09:21:04

相似问题

登录后可查看更多问答,登录/注册

问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信