Vue源碼之 怎樣顯示組件節點內部的節點

好比javascript

<template>
  <child name='a'><div id='demo'>組件節點內部節點</div></child>
</template>

父節點內部有個child組件節點,不在child的template而是直接在節點內部寫節點,好比element的不少地方都是這樣作的。vue

那麼問題來了,直接這樣寫是顯示不出來的,element是怎樣作到的呢?java

咱們知道,父組件生成虛擬節點,子節點數組中每一個元素的形式是 標籤-data-子節點數組,好比child這個虛擬節點就是{tag:child,data:{name:'a'},children:[div對應的虛擬節點]},因此id='demo'的信息實際上是在虛擬節點的children屬性中,node

若是child組件中有本身的template,優先用本身的template生成實際節點,忽略掉children屬性中的子節點。數組

那麼若是想顯示children中的子節點,就須要去掉child內部的template,換成script中自定義的render函數,好比寫成下面這樣(其實能夠簡化一下),用render函數生成真實節點。async

render() {
      return (<div>{[(<div>{this.$slots.default}</div>)]}</div>)
    }

問題:this.$slots.default是啥?函數

Vue源碼6161行patch方法(這時候是在父組件的watcher的update方法中調用patch方法),在第一次建立週期的時候是從6208行的createElm一路createChildren這樣找到child節點,調用createElm來建立child節點,由於child是個組件節點,因此進入5627行的createComponent方法,在5678行調用4213行的init方法(這個是掛載在data上的組件節點專用的初始化方法,和下面的_init方法不同),生成child的VueComponent對象vm,生成vm的時候,vm._init方法中有initRender方法this

裏面有spa

vm.$slots = resolveSlots(options._renderChildren, renderContext);

這句話,簡單理解就是把options._renderChildren數組中的元素放入vm.$slots.default數組中component

那麼_renderChildren又是什麼?在_init方法中,initRender以前有個initInternalComponent方法,在裏面發現是parentVnode.componentOptions的children屬性,parentVnode又是options._parentVnode,回頭去找options,這裏的_init方法是在上面說的4213行的init方法中,在調用createComponentInstanceForVnode---->new vnode.componentOptions.Ctor,這裏的options._parentVnode就是傳入的vnode,這個vnode就是child對應的虛擬節點,

那麼vnode中的componentOptions的children屬性在哪?那要去vnode生成的時候的_c方法中去看,4586行的_c一直點下去,4517行,createComponent

var vnode = new VNode(
            ("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')),
            data, undefined, undefined, undefined, context,
            { Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children },
            asyncFactory
        );

  

對比VNode的構造函數,發現componentOptions就是{ Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children }這個對象,children: children,這個children是createComponent的參數,

其實就是父組件生成child節點時候的的children屬性。

相關文章
相關標籤/搜索