Vue源码解读之Component组件注册的实现

时间:2021-05-26

什么是组件?

组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以表现为用 is 特性进行了扩展的原生 HTML 元素。

所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。

Vue可以有全局注册和局部注册两种方式来注册组件。

全局注册

注册方式

全局注册有以下两种注册方式:

通过Vue.component 直接注册。

Vue.component('button-counter', { //data选项必须是一个函数 data: function () { return { count: 0 } }, template:'#clickBtn' })

通过Vue.extend来注册。

var buttonComponent = Vue.extend({ name:'button-counter', data: function () { return { count: 0 } }, template:'#clickBtn' }); Vue.component('button-counter', buttonComponent);

具体过程

Vue初始化时,initGlobalAPI通过调用initAssetRegisters()进行组件注册。

function initAssetRegisters (Vue) { // 创建组件注册的方法 // ASSET_TYPES在Vue内部定义,var ASSET_TYPES = ['component','directive','filter']; ASSET_TYPES.forEach(function (type) { Vue[type] = function ( id, definition ) { //这里的definition指的是定义(Function或Object),是函数或者对象 //如果definition不存在,直接返回options内type和id对应的 //这里的options是指全局的组件,指令和过滤器,见图一 if (!definition) { return this.options[type + 's'][id] } else { if ("development" !== 'production' && type === 'component') { validateComponentName(id); } // 如果是component(组件)方法,并且definition是对象 if (type === 'component' && isPlainObject(definition)) { definition.name = definition.name || id; //通过this.options._base.extend方法(也就是Vue.extend方法)将定义对象转化为构造器。 //Vue.options._base = Vue; definition = this.options._base.extend(definition); } if (type === 'directive' && typeof definition === 'function') { definition = { bind: definition, update: definition }; } // 将构造器赋值给 this.options[‘component'+ 's'][id] //全局的组件,指令和过滤器,统一挂在vue.options上。在init的时候利用mergeOptions合并策略侵入实例,供实例使用。 this.options[type + 's'][id] = definition; return definition } }; });}

图一:

initAssetRegisters里面通过this.options._base.extend方法将定义对象转化为构造器,而options._base.extend其实就是Vue.extend。接下来我们就看一下Vue.extend做了什么。

Vue.extend = function (extendOptions) { extendOptions = extendOptions || {}; var Super = this; var SuperId = Super.cid; //组件缓存 var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {}); //如果组件已经被缓存在extendOptions上则直接取出 if (cachedCtors[SuperId]) { return cachedCtors[SuperId] } //如果有name属性,检验name拼写是否合法 var name = extendOptions.name || Super.options.name; if ("development" !== 'production' && name) { validateComponentName(name); } var Sub = function VueComponent (options) { this._init(options); }; //将vue上原型的方法挂在Sub.prototype中,Sub的实例同时也继承了vue.prototype上的所有属性和方法。 //关于 prototype的学习:http://ponents-demo"> <button-counter></button-counter></div>

可参考:https://www.jb51.net/article/144050.htm

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章