1.7 自带资源选项合并

在1.2中我们看到了Vue默认会带几个选项,分别是components组件, directive指令, filter过滤器,所有无论是根实例,还是父子实例,都需要和系统自带的资源选项进行合并。它的定义如下:

  1. // 资源选项
  2. var ASSET_TYPES = [
  3. 'component',
  4. 'directive',
  5. 'filter'
  6. ];
  7. // 定义资源合并的策略
  8. ASSET_TYPES.forEach(function (type) {
  9. strats[type + 's'] = mergeAssets; // 定义默认策略
  10. });

这些资源选项的合并逻辑很简单,首先会创建一个原型指向父类资源选项的空对象,再将子类选项赋值给空对象。

  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. }

结合下面的例子,我们看具体合并后的结果:

  1. var vm = new Vue({
  2. components: {
  3. componentA: {}
  4. },
  5. directives: {
  6. 'v-boom': {}
  7. }
  8. })
  9. console.log(vm.$options.components)
  10. // 根实例的选项和资源默认选项合并后的结果
  11. {
  12. components: {
  13. componentA: {},
  14. __proto__: {
  15. KeepAlive: {}
  16. Transition: {}
  17. TransitionGroup: {}
  18. }
  19. },
  20. directives: {
  21. 'v-boom': {},
  22. __proto__: {
  23. 'v-show': {},
  24. 'v-model': {}
  25. }
  26. }
  27. }

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