vue源码解读--组件注册

目录导航

我们这一节的例子如下

vue源码解读--组件注册_第1张图片
(全局注册app.vue组件)
vue源码解读--组件注册_第2张图片
(局部注册child组件)

由于我们一开始调用了Vue.component方法,因此查找component方法的定义

可以发现在src\shared\constants.js中进行了声明

vue源码解读--组件注册_第3张图片

并在src\core\global-api\assets.js中的initAssetRegisters方法上向vue上进行了挂载,而initAssetRegisters则在import vue时执行

vue源码解读--组件注册_第4张图片

因此该方法完整形式为  Vue.component=function(id,definition){}

        a-该方法接收两个参数,一个是字符串,即'App';一个是函数或对象,即我们传递的'组件对象'

        b-首先对我们传递的id进行校验,调用validateComponentName

vue源码解读--组件注册_第5张图片

                vue要求组件名称必须合法并且不能是html内置组件,因为vue在patch过程中会优先创建内置组件,在处理组件注册时会尝试多形式引入

        c-我们这里type为component且definition为普通对象,进入判断

                definition.name="App"

                this.options._base即Vue,因此这里调用的实际上是Vue.extend方法,经过之前文章的分析我们知道这实际上是创建一个组件的构造器,在这一过程有几个点比较重要

vue源码解读--组件注册_第6张图片

                        将Sub的原型指向Vue的原型,这样vue在尝试resolve的时候就能够查找到

                        通过mergeOptions将component合并到组件的配置对象上,这样vue在尝试查找时候就不会一直查找到原型

        d-这样我们已经完成了组件注册的初始化工作,当执行new vue后按照惯例去init-mount-render,但是这次我们走render的逻辑会稍微的有些不一样

                调用resolveAsset,入参('配置对象','components',组件的根元素即'app')

vue源码解读--组件注册_第7张图片

                        拿到配置对象的components方法,这里components非undefined,这是因为在Vue.extend过程中执行了mergeOptions方法将components合并到组件的options上,但是这里组件的options上的components实际上为{},这是因为在extend最后执行了

(而super上的components为{})

                        接着调用hasOwnProperty判断对象的key是否是继承自prototype,是则false,否则true,也就是说会先在自身进行查找如果没有则camelize转为驼峰格式,如果还没有则转为首字符大写,若依旧查不到,则向原型上找,因为我们在extend时执行了Object.create(),因此有权向上访问,即

(这里便拿到了原型上的app组件构造器)

        e-我们拿到了组件的构造器进入判断执行createComponent,本次创造组件的过程不会再次extend,因为我们已经在Vue.component时调用了extend将组件转为为了构造器,故不满足object

  至此组件的注册便已经完成,后续的uodate一级调用patch转为dom就都跟之前一样了。有一点需要注意的是,不管是全局注册的组件还是局部注册的实际上都会执行vue.extend方法去生成一个构造器,只不过全局的先执行,那时候的this指向vue,挂载的对象也是顶层的vue,而每一次又都通过Object.create方法将组件的options指向了父级的原型,因此子组件中也可以去使用全局注册的组件;而对于子组件而言它的extend的options是指向自身的,而vue的查找顺序也是先子后父的,因此挂载到子组件的component只能在子组件内部使用

你可能感兴趣的:(vue源码解读--组件注册)