简单看一下mixin

2021-03-29  本文已影响0人  HelenYin

其实mixin的功能就是把传入的option和组件本身的option做merge
这样思考就超简单了,只需要调用mergeOptions就可以了。

mergeOptions(this.options, mixins)

这里说一下mergeOptions。mergeOptions是对传入的option进行合并的方法。
例如: 本来组件里调用了created生命周期,mixin里又传入了created,那么定义的这两个created放入一个队列里,在生命周期执行到created的时候,依次执行这个队列里的方法。
这里我们可以看一下callHook这个函数

export function callHook (vm, hook) {
  // 拿到对应的队列
  const handlers = vm.$options[hook];
  if (handlers) {
    for (const handle of handlers) {
      handle.call(vm);
    }
  }
}

因为目前实现的功能简单,只做生命周期的merge
首先遍历组件本身的option,再遍历mixins传入的对象

function mergeOptions (parent, child) {
  const options = {};

  for (const key in parent) {
    mergeField(key);
  }

  for (const key in child) {
    if (!hasOwnProperty.call(parent, key)) {
      mergeField(key);
    }
  }

  function mergeField (key) {
    const strat = strats[key] || defaultStrat;
    options[key] = strat(parent[key], child[key]);
  }

  return options;
}
function mergeHook (parentVal, childVal) {
  return childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : Array.isArray(childVal)
        ? childVal
        : [childVal]
    : parentVal;
}

LIFECYCLE_HOOKS.forEach((hook) => {
  strats[hook] = mergeHook;
});
export const LIFECYCLE_HOOKS = [
  'beforeCreate',
  'created',
  'beforeMount',
  'mounted',
  'beforeUpdate',
  'updated',
  'beforeDestroy',
  'destroyed',
  'activated',
  'deactivated',
  'errorCaptured'
]

现在看一下到目前为止哪些地方调用了mergeOptions:

  1. Vue.prototype._init 方法中,也就是实例化Vue的时候,也就是第一次调用new Vue()的时候
vm.$options = mergeOptions(vm.constructor.options, options, vm)
  1. Vue.extends 方法中,也就是实例化组件时候
Vue.extend = function (extendOptions) {
  const Super = this;
  Sub.options = mergeOptions(Super.options, extendOptions);
}

这两类都是把类的options属性和传入的options做merge。
这样看来,如果直接调用Vue.mixin()那么后面所有的组件的options中都具备了mixin

上一篇下一篇

猜你喜欢

热点阅读