1.5 资源选项的自定义策略

在上一节中,我们知道Vue构造函数自身有options的配置选项,分别是components组件, directive指令, filter过滤器,在创建实例之前,程序会将内置组件和内置指令分别挂载到components和directive属性上。

  1. var ASSET_TYPES = [
  2. 'component',
  3. 'directive',
  4. 'filter'
  5. ];
  6. ASSET_TYPES.forEach(function (type) {
  7. Vue.options[type + 's'] = Object.create(null); // Vue构造器拥有的默认资源选项配置
  8. });
  9. // Vue内置组件
  10. var builtInComponents = {
  11. KeepAlive: KeepAlive
  12. };
  13. var platformComponents = {
  14. Transition: Transition,
  15. TransitionGroup: TransitionGroup
  16. };
  17. // Vue 内置指令,例如: v-model, v-show
  18. var platformDirectives = {
  19. model: directive,
  20. show: show
  21. };
  22. // 将_from对象合并到to对象,属性相同时,则覆盖to对象的属性
  23. function extend (to, _from) {
  24. for (var key in _from) {
  25. to[key] = _from[key];
  26. }
  27. return to
  28. }
  29. extend(Vue.options.components, builtInComponents);
  30. extend(Vue.options.components, platformComponents); // 扩展内置组件
  31. extend(Vue.options.directives, platformDirectives); // 扩展内置指令

构造函数的默认资源选项配置如下:

  1. Vue.options = {
  2. components: {
  3. KeepAlive: {}
  4. Transition: {}
  5. TransitionGroup: {}
  6. },
  7. directives: {
  8. model: {inserted: ƒ, componentUpdated: ƒ}
  9. show: {bind: ƒ, update: ƒ, unbind: ƒ}
  10. },
  11. filters: {}
  12. _base
  13. }

在实例化Vue,或者实例化子类时,这一类资源选项是如何合并的呢?

  1. // 资源选项自定义合并策略
  2. function mergeAssets (parentVal,childVal,vm,key) {
  3. var res = Object.create(parentVal || null); // 创建一个空对象,其原型指向父类的资源选项。
  4. if (childVal) {
  5. assertObjectType(key, childVal, vm); // components,filters,directives选项必须为对象
  6. return extend(res, childVal) // 子类选项赋值给空对象
  7. } else {
  8. return res
  9. }
  10. }
  11. ASSET_TYPES.forEach(function (type) {
  12. strats[type + 's'] = mergeAssets; // 定义默认策略
  13. });

简单总结一下,对于 directives、filters 以及 components 等资源选项,父类选项将以原型链的形式被处理。子类必须通过原型链才能查找并使用内置组件和内置指令。