请稍等 ...
×

采纳答案成功!

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

有点搞不懂 patch 中 createComponent 中的 i.init 等这些 hook 被注册和被调用的顺序了

我想知道下面结构中 child 组件的 i.init hook 被调用之前是在什么时机被注册的(PS:我知道注册的代码片段是 installComponentHooks,只是我断点想不通注册和调用的先后顺序):

<div id="app">
   <child :msg="msg"></child>
 </div>

我看到的顺序是这样的

  • 从 app 根节点的 patch 开始,patch 中 createElm 创建根 div 后,然后因为 app 这个根节点不是组件,所以会进入后面的 createChildren 方法创建子组件,这时候 createChildren 中的 createElm 执行后会进入 createComponent,然后就开始调用 i.init hook 了;这里我有疑惑;就是这个 hook 我看到是在 create-component.js 文件中的 createComponent 方法中的 installComponentHooks 方法中注册的 hook;但是我看到这里的 createComponent 其实是走的 $mount -> mountComponent -> _render 中的 $createElement 中进入到这个 createComponent 的;这里我开始不懂了;因为组件的 $mount 是要在 i.init hook 中的 createComponentInstanceForVnode 之后才会调用 child.$mount 方法;但是 hook 又是在 createComponent 中注册的;我就被绕晕了,怎么感觉 child.$mount 还没调用,组件自己的 hook 就已经注册好了;我感觉我应该是我印象中的父子顺序出现了问题;
  • 不知道黄老能不能看懂我的疑惑;

正在回答

1回答

举个例子,模板
<div id="app">
  <hello></hello>
</div>

会编译成 render 函数

function render() {

  with(this) {

    return _c('div', {

      attrs: {

        "id": "app"

      }

    }, [_c('hello')], 1)

  }

}


render  函数执行的时候就会执行 _c 也就是 createElement 函数创建 vnode 节点,其中 hello 标签并非保留标签,会尝试从 components 中拿,如果注册了,就当成自定义组件执行 createComponent 方法,在执行这个函数的过程中,就会执行 installComponnetHooks 给渲染数据中添加这些钩子函数,比如 init,所以在后续 patch App 组件的时候,遍历遇到 hello 这个组件 vnode 节点,就可以执行这个 init 函数了。

1 回复 有任何疑惑可以回复我~
  • 提问者 染丶墨3614535 #1
    hmmm,这个在编译成 render 的时候,这时候还是没有调用 _c 把?
    
    我的理解是在 hello 组件的 $mount -> mountComponent -> _update -> _render 这里才调用到 render 把;然而 hello 组件的 $mount 我的理解好像是在 i.init 那个 hook 中的 child.$mount 才调到,但实际情况应该是得先调用一次这个 _c 注册组件hook后,才应该走 #app 的 patch 里面的 createChildren -> createElm -> createComponent -> i.init;所以我的想法应该漏了什么东西;
    
    或者黄老的意思是在编译成 _c('hello') 的时候,就已经执行了 组件 _c('hello'),然后才走的 #app 的 patch 流程?
    回复 有任何疑惑可以回复我~ 2021-04-26 17:13:30
  • ustbhuangyi 回复 提问者 染丶墨3614535 #2
    你要搞清楚,这个 render 是 App 组件 mount 的时候执行的,这里面压根就没有 hello 组件啥事情。
    回复 有任何疑惑可以回复我~ 2021-04-26 17:27:01
  • 提问者 染丶墨3614535 回复 ustbhuangyi #3
    o O 哦。。。!!!!!懂了;这个是 App 根组件的 $mount -> 中调用 render 的时候,就把整个编译模板中的 _c 函数都执行完了是这样吧;谢谢黄老科普;这里可能要在后面编译流程中要细看一下模板编译部分了;感谢黄老努力工作的时候还在回复让黄老看笑话的问题;5
    回复 有任何疑惑可以回复我~ 2021-04-26 17:46:42
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号