在vue中组件注册有两种方式,第一种是全局注册Vue.component('my-component', { }),第二种是局部注册:
import HelloWorld from './components/HelloWorld'
export default {
components: {
HelloWorld //局部注册
}
}
先看Vue.component的函数是如何定义:
1.在Vue初始化的过程中会执行initAssetRegisters函数并把Vue当成参数传入,执行的过程中遍历ASSET_TYPES数组,该数组存放了三个参数['component','directive','filter']将每一个参数都定义在Vue上并赋值为函数,函数的入参是id(传入的组件name)和definition(传入的组件,可以是函数或者对象),函数的执行逻辑是当definition不存在时直接返回Vue.options.components.id(组件对象)。
2.当definition存在时会走到代码第21行中,判断为对象后会去判断definition是否存在name如果不存在,则使用传入的参数id作为name,然后执行this.options._base.extend方法,该方法其实就是使用了Vue.extend方法将definition转换为构造器,并将这个构造器放到了Vue.options.components.id上,然后返回该构造器。
3.全局注册组件后,其他组件是如何拿到注册的组件呢?在创建组件Vnode的过程中会执行_createElement方法,该方法内部会执行isDef(Ctor = resolveAsset(context.$options, 'components', tag))其中的resolveAsset函数源码参数中有options(Vue.options和自定义配置合并而来)和type、id(组件的name)参数,该函数内部会先去拿到options.components并赋值给assets,在assets内部属性找id如果找不到会将id转成驼峰或者是首字母大写的形式再去找,还是找不到就再去原型对象上找,最后会找到Vue.options.components上的definition构造器并返回。返回后会用传入createComponent函数生成一个组件VNode vnode = createComponent(Ctor, data, context, children, tag);这个过程就是任意组件去Vue.options.components获取注册组件的过程。
局部注册的过程:在Vue.extends函数中会有Sub.options = mergeOptions(Super.options,extendOptions )
mergeOptions中的super参数指的Vue,extendOptions指的是定义的组件对象,该函数会将这两个options合并到Sub.options上(Sub是我们自己定义的组件对象)。然后组件初始化中会去调用initInternalComponent函数,这个函数中有const opts = vm.$options = Object.create(vm.constructor.options) 其中vm.constructor就是Sub,那么自定义组件可在this.$options.components拿到注册的组件。