在createElment函数创建vnode时,如果判断tag标签是组件的话,会调用createComponent函数创建vnode

在createComponent(定义在'src/core/vdom/create-component.js')中,首先是获得基础构造器baseCtor。这里的context是指向vm实例。


在'globalp-api/index.js'中,可以看到option._base指向的是Vue


而在'core/instance/init.js'中,已经将全局的options与vm实例的options合并,这样baseCtor指向的就是Vue

然后对组件的构造器Ctor进行扩展,实际上执行的是Vue.extend。extend函数在'core/gloabal-api/extend.js'中定义



以下时候Vue的工具方法extend函数。它主要的功能是返回一个组件构造器(函数),拥有Vue相同的功能

首先,Super指向Vue,同时指定一个SuperId,并且定义一个缓存构造器cachedCtors用来缓存构造器,然后检查组件的名字是否合法。



然后创建一个sub函数,用来继承Super(Vue),这里的继承使用的是Object.create()函数,该函数的功能是把某个对象(对应这里的Sub.prototype)的__proto__属性关联到指定的对象。



然后对Sub的props和computed做初始化,并扩展一些方法和属性,最后将Sub缓存起来,下次如果对应的cachedCtors中有对应的值,就直接返回,不用再创建一个组件的构造器。



回到createComponent函数中,创建Ctor之后判断是不是函数,不是的话则抛出警告。然后开始对data进行一些处理。重要的是使用installComponentHooks处理组件的钩子函数。



在installComponentHooks函数中,先拿到data中的hook,然后循环hooksToMerge进行判断,如果data中存在该hook,则合并,不存在则直接添加到data中。hooksToMerge定义为componentVNodeHooks的keys。componentVNodeHooks的定义如下图所示。




回到createComponent函数中,在处理完了hooks之后,会创建一个以'vue-component'开头的vnode,值得注意的是这个vnode中的children定义的是undefined,而在最后一个参数componentOptions中,传入了children。然后返回vnode



总结

在创建组件vnode时,主要的步骤是先建立一个组件构造器,这样可以实例化组件。其中对构造器进行扩展,使得具有Vue的功能和方法,然后对data进行一些处理,其中重要的是将组件vnode的hook与data中的hook合并。在处理完之后,新建一个vnode返回。

Logo

前往低代码交流专区

更多推荐