1.5 资源选项的自定义策略
在上一节中,我们知道Vue构造函数自身有options的配置选项,分别是components组件, directive指令, filter过滤器,在创建实例之前,程序会将内置组件和内置指令分别挂载到components和directive属性上。
var ASSET_TYPES = [
'component',
'directive',
'filter'
];
ASSET_TYPES.forEach(function (type) {
Vue.options[type + 's'] = Object.create(null); // Vue构造器拥有的默认资源选项配置
});
// Vue内置组件
var builtInComponents = {
KeepAlive: KeepAlive
};
var platformComponents = {
Transition: Transition,
TransitionGroup: TransitionGroup
};
// Vue 内置指令,例如: v-model, v-show
var platformDirectives = {
model: directive,
show: show
};
// 将_from对象合并到to对象,属性相同时,则覆盖to对象的属性
function extend (to, _from) {
for (var key in _from) {
to[key] = _from[key];
}
return to
}
extend(Vue.options.components, builtInComponents);
extend(Vue.options.components, platformComponents); // 扩展内置组件
extend(Vue.options.directives, platformDirectives); // 扩展内置指令
构造函数的默认资源选项配置如下:
Vue.options = {
components: {
KeepAlive: {}
Transition: {}
TransitionGroup: {}
},
directives: {
model: {inserted: ƒ, componentUpdated: ƒ}
show: {bind: ƒ, update: ƒ, unbind: ƒ}
},
filters: {}
_base
}
在实例化Vue,或者实例化子类时,这一类资源选项是如何合并的呢?
// 资源选项自定义合并策略
function mergeAssets (parentVal,childVal,vm,key) {
var res = Object.create(parentVal || null); // 创建一个空对象,其原型指向父类的资源选项。
if (childVal) {
assertObjectType(key, childVal, vm); // components,filters,directives选项必须为对象
return extend(res, childVal) // 子类选项赋值给空对象
} else {
return res
}
}
ASSET_TYPES.forEach(function (type) {
strats[type + 's'] = mergeAssets; // 定义默认策略
});
简单总结一下,对于 directives、filters 以及 components 等资源选项,父类选项将以原型链的形式被处理。子类必须通过原型链才能查找并使用内置组件和内置指令。