new Vue() 到beforeCreate()用到的几个方法

1,457 阅读1分钟

Vue 构造函数

function Vue (options) {
	if (!(this instanceof Vue)
	) {
	  warn('Vue is a constructor and should be called with the `new` keyword');
	}
	this._init(options);
}

Vue.prototype._init

vm._uid = uid$3++; (给每个实例分配一个自增id)

给当前实例标记,源码注释: a flag to avoid this being observed

vm._isVue = true;

合并参数

判断当前实例是否为组件
if (options && options._isComponent) {
	// optimize internal component instantiation
	// since dynamic options merging is pretty slow, and none of the
	// internal component options needs special treatment.
	initInternalComponent(vm, options);
} else {
	处理options参数,合并参数
	vm.$options = mergeOptions(
		resolveConstructorOptions(vm.constructor),
		options || {},
		vm
	);
}

initInternalComponent方法处理组件

function initInternalComponent (vm, options) {
    var opts = vm.$options = Object.create(vm.constructor.options);
    // doing this because it's faster than dynamic enumeration.
    var parentVnode = options._parentVnode;
    opts.parent = options.parent;
    opts._parentVnode = parentVnode;

    var vnodeComponentOptions = parentVnode.componentOptions;
    opts.propsData = vnodeComponentOptions.propsData;
    opts._parentListeners = vnodeComponentOptions.listeners;
    opts._renderChildren = vnodeComponentOptions.children;
    opts._componentTag = vnodeComponentOptions.tag;

    if (options.render) {
      opts.render = options.render;
      opts.staticRenderFns = options.staticRenderFns;
    }
  }
  在options上加上一些属性

resolveConstructorOptions方法返回options参数

	参数Ctor是Vue构造函数(vm.constructor)
	function resolveConstructorOptions (Ctor) {
	
		var options = Ctor.options;
		如果是new Vue调用,options就是源码中的 initGlobalAPI 方法会在初始化脚本时候给Vue构造函数增加options属性。
		如果是Vue.extend调用,options就是 Vue.extend 方法中给VueComponent构造函数增加的options属性。
		
		if (Ctor.super) { //判断是否为Vue.extend创建的一个“子类” Vue.extend方法中会加上super属性
			var superOptions = resolveConstructorOptions(Ctor.super);
			此时的Ctor是VueComponent构造函数,
			Ctor.super为Vue构造函数 ( Vue.extend 中定义),所以这个返回值是 initGlobalAPI 方法会在初始化脚本时候给Vue构造函数增加options属性。
			
			var cachedSuperOptions = Ctor.superOptions;
			返回值是Vue.extend中定义的superOptions
			
			if (superOptions !== cachedSuperOptions) {
				检查Vue的options是否发生变化
				superOptions有新变化则缓存superOptions 列如Vue.mixin()
				// super option changed,
				// need to resolve new options.
				Ctor.superOptions = superOptions;
				// check if there are any late-modified/attached options (#4976)
				
				检查"自身"的options是否发生变化
				var modifiedOptions = resolveModifiedOptions(Ctor);
				
				// update base extend options
				更新修改的options
				if (modifiedOptions) {
				    extend(Ctor.extendOptions, modifiedOptions);
				}
				合并参数
				options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions);
				if (options.name) {
				    options.components[options.name] = Ctor;
				}
			}
		}
		return options
	}

resolveModifiedOptions 方法返回update的属性

function resolveModifiedOptions (Ctor) {
    var modified;
    var latest = Ctor.options;
    var sealed = Ctor.sealedOptions;  这个值为 Vue.extend() 中定义
    for (var key in latest) {
      if (latest[key] !== sealed[key]) {  判断两个options的key是否相等
        if (!modified) { modified = {}; }
        modified[key] = latest[key];  取最新的值
      }
    }
    return modified
}

mergeOptions

	/**
   * Merge two option objects into a new one.
   * Core utility used in both instantiation and inheritance.
   */
  function mergeOptions (
    parent,
    child,
    vm
  ) {
    {
      checkComponents(child);
      检测组件的命名规范
    }

    if (typeof child === 'function') {
      child = child.options;
    }

    normalizeProps(child, vm);   规范化,Props 转为对象
    normalizeInject(child, vm);	规范化,Inject 转为对象
    normalizeDirectives(child);	规范化,Inject 转为对象

    // Apply extends and mixins on the child options,
    // but only if it is a raw options object that isn't
    // the result of another mergeOptions call.
    // Only merged options has the _base property.
    不是根组件的话 调用自身合并option参数
    if (!child._base) {
      if (child.extends) {
        parent = mergeOptions(parent, child.extends, vm);
      }
      if (child.mixins) {
        for (var i = 0, l = child.mixins.length; i < l; i++) {
          parent = mergeOptions(parent, child.mixins[i], vm);
        }
      }
    }

    var options = {};
    var key;
    for (key in parent) {
      mergeField(key);
    }
    for (key in child) {
      if (!hasOwn(parent, key)) {
        mergeField(key);
      }
    }
    strats为合并策略,分别用不用的方法合并options参数 (data, created, methods 等等)
    function mergeField (key) {
      var strat = strats[key] || defaultStrat;
      options[key] = strat(parent[key], child[key], vm, key);
    }
    return options
  }

initProxy

	function initProxy (vm) {
      if (hasProxy) {
        // determine which proxy handler to use
        var options = vm.$options;
        var handlers = options.render && options.render._withStripped
          ? getHandler
          : hasHandler;
        vm._renderProxy = new Proxy(vm, handlers);
      } else {
        vm._renderProxy = vm;
      }
    };
    这个方法主要给vm增加一个_renderProxy属性,并且代理到vm上,之后_render()的时候会用到

initLifecycle(vm);

initEvents(vm);

initRender(vm);

这三个方法主要是是初始化一些_watcher,_isMounted等属性,以及listeners事件,$createElement方法

在new Vue() 到beforeCreate之间主要是合并optoins参数,如用到了mixins,extends等,并且初始化一些属性