Vue.mixin Vue.extend(Vue.component)的原理与…
2018-11-29 09:46:57来源:博客园 阅读 ()
1.本文将讲述 方法 Vue.extend Vue.mixin 与 new Vue({mixins:[], extend:{}})的区别与原理
先回顾一下 Vue.mixin 官网如下描述:
Vue.mixin( mixin )全局注册一个混入,影响注册之后所有创建的每个 Vue 实例。插件作者可以使用混入,向组件注入自定义的行为。
既然可以影响到注册后的所有实例,那么该方法注入的方法和属性都存放在哪里呢(构造函数的options属性上),我们一起来看看该方法的定义
Vue.mixin = function (mixin) {
//mergeOption,将Vue构造函数的Options属性与传入的mixin参数进行合并,
//合并之后再复制给Vue构造函数的Options属性
this.options = mergeOptions(this.options, mixin);
return this
};
为什么Vue.mixin方法将mixin合并至Vue.options就能影响注册之后的所有实例呢,让我们看看Vue实例化的过程(将构造函数的options属性与实例化参数合并后付给实例的$options属性
)
1 function Vue(options) { 2 //调用_init方法 3 this._init(options); 4 } 5 6 7 8 Vue.prototype._init = function (options) { 9 var vm = this; 10 // a uid 11 vm._uid = uid$3++; 12 13 var startTag, endTag; 14 21 // a flag to avoid this being observed 标记该对象是一个Vue实例 22 vm._isVue = true; 23 // merge options 24 if (options && options._isComponent) { //组件实例化过程,即Vue.extend返回对象--稍后解释 25 // optimize internal component instantiation 26 // since dynamic options merging is pretty slow, and none of the 27 // internal component options needs special treatment. 28 initInternalComponent(vm, options); 29 } else {//将构造函数的options属性与实例化参数合并后付给实例的$options属性 ,该属性会在函数initState中进行初始化 30 vm.$options = mergeOptions( 31 resolveConstructorOptions(vm.constructor), 32 options || {}, 33 vm 34 ); 35 } 36 /* istanbul ignore else */ 37 { 38 initProxy(vm); 39 } 40 // expose real self 41 vm._self = vm; 42 initLifecycle(vm); 43 initEvents(vm); 44 initRender(vm); 45 callHook(vm, 'beforeCreate'); 46 initInjections(vm); // resolve injections before data/props 47 initState(vm); 48 initProvide(vm); // resolve provide after data/props 49 callHook(vm, 'created'); 50 51 /* istanbul ignore if */ 52 if ("development" !== 'production' && config.performance && mark) { 53 vm._name = formatComponentName(vm, false); 54 mark(endTag); 55 measure(("vue " + (vm._name) + " init"), startTag, endTag); 56 } 57 58 if (vm.$options.el) { 59 vm.$mount(vm.$options.el); 60 } 61 };
Vue.extend-- 使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象
该方法返回一个与Vue具有相同功能的构造函数(其实为创建了一个组件)-属性options是 合并 基础 Vue 构造器 与 extend的参数 的对象,
Vue.extend = function (extendOptions) { extendOptions = extendOptions || {}; //将调用函数付给Super var Super = this; var SuperId = Super.cid; //如果参数中参入与创建的构造函数则直接返回 var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {}); if (cachedCtors[SuperId]) { return cachedCtors[SuperId] } //获取组件的名称 var name = extendOptions.name || Super.options.name; if ("development" !== 'production' && name) { validateComponentName(name); } //创建组件Sub var Sub = function VueComponent(options) { this._init(options); };
//为组件添加对应的属性与方法 Sub.prototype = Object.create(Super.prototype); Sub.prototype.constructor = Sub; Sub.cid = cid++;
//合并super的options与extend的入参并赋值给Sub的options属性 Sub.options = mergeOptions( Super.options, extendOptions );
//在sub上保存Super的信息 Sub['super'] = Super; // For props and computed properties, we define the proxy getters on // the Vue instances at extension time, on the extended prototype. This // avoids Object.defineProperty calls for each instance created. if (Sub.options.props) { initProps$1(Sub); } if (Sub.options.computed) { initComputed$1(Sub); } // allow further extension/mixin/plugin usage Sub.extend = Super.extend; Sub.mixin = Super.mixin; Sub.use = Super.use; // create asset registers, so extended classes // can have their private assets too. ASSET_TYPES.forEach(function (type) { Sub[type] = Super[type]; }); // enable recursive self-lookup
//如果有组件名称,将该组件挂载到sub.options.components上。以便可在组件内使用
if (name) { Sub.options.components[name] = Sub; } // keep a reference to the super options at extension time. // later at instantiation we can check if Super's options have // been updated.
//保存option信息。以便在render的时候生成最新的options选项
Sub.superOptions = Super.options; Sub.extendOptions = extendOptions; Sub.sealedOptions = extend({}, Sub.options); // cache constructor cachedCtors[SuperId] = Sub; return Sub //返回sub构造函数 };
Vue.component( id, [definition] ) 注册或获取全局组件。注册还会自动使用给定的id
设置组件的名称,第二个参数可以是Object也可以调用Vue.extend 返回的构造函数,返回组件
调用Vue.component 将调用Vue.extend生成一个组件(构造函数),该组件将赋值给Vue.options.components[id],由于在实例化时,将合并构造函数的options至实例对象的$options上,所有通过通过全局构造函数Vue创建的组件或者视图都可以运用该组件,
var ASSET_TYPES = [ 'component', 'directive', 'filter' ]; //定义 Vue.component . Vue.directive Vue.filter ASSET_TYPES.forEach(function (type) { Vue[type] = function ( id, definition ) { if (!definition) { return this.options[type + 's'][id] } else { /* istanbul ignore if */ if ("development" !== 'production' && type === 'component') { //对组件的命名规范进行验证 validateComponentName(id); } if (type === 'component' && isPlainObject(definition)) { //如果第二个参数是一个Object 调用 Vue.extend(definition)生成一个构造函数 this.options._base === Vue definition.name = definition.name || id; definition = this.options._base.extend(definition); } if (type === 'directive' && typeof definition === 'function') { definition = { bind: definition, update: definition }; } //将Vue.options.components[id]赋值为 组件构造函数 this.options[type + 's'][id] = definition; return definition } }; }); }
由以上代码可见 Vue.component返回的组件即为 Vue.extend创建的构造函数 -再次命名为subVue,subVue具有与Vue一样的方法和属性,所以可调用subVue.component,subVue.extend创建组件,调用subVue.component,subVue.extend创建的组件组件将存放于subVue.options上,所以在通过subVue创建的组件,只能用于subVue实例化传入字符串模板的中模板使用,或者subVue.component,subVue.extend创建的组件实例化传入的字符串模板中使用。
new Vue({mixins:[], extend:{}})
实例化选项mixins , extend将在init函数中通过mergeOptions合并至实例属性$options,他们的区别是extend为options对象,mixins为options数组,同时 extend的方法将比mixins先执行,但他们都会在 Vue.extend 与 Vue.mixin之后 执行
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:cssText用法和使用说明
下一篇:小程序保存图片到相册功能实现
- Vue组件 2018-07-25
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash