vue 学习中知识总结

2022-03-23 14:09:23 浏览数 (1)

1、Vue 的初始化过程(new Vue(options))都做了什么?

在main.js 加入如下代码

代码语言:javascript复制
debugger
new Vue(
  {
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

Chrome浏览器调试

截屏2022-03-01 下午2.27.46.png

代码语言:javascript复制
function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword');
  }
  this._init(options);
}

下一步

代码语言:javascript复制
function initMixin (Vue) {
// 负责 Vue 的初始化过程
  Vue.prototype._init = function (options) {
// vue 实例
    var vm = this;
    // a uid 每个 vue 实例都有一个 _uid,并且是依次递增的
    vm._uid = uid$3  ;

    var startTag, endTag;
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
      startTag = "vue-perf-start:"   (vm._uid);
      endTag = "vue-perf-end:"   (vm._uid);
      mark(startTag);
    }

    // a flag to avoid this being observed
    vm._isVue = true;
    // merge options
    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 {
      /**
       * 初始化根组件时走这里,合并 Vue 的全局配置到根组件的局部配置,比如 Vue.component 注册的全局组件会合并到 根实例的 components 选项中
       * 至于每个子组件的选项合并则发生在两个地方:
       *   1、Vue.component 方法注册的全局组件在注册时做了选项合并
       *   2、{ components: { xx } } 方式注册的局部组件在执行编译器生成的 render 函数时做了选项合并,包括根组件中的 components 配置
       */
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      );
    }
    /* istanbul ignore else */
    if (process.env.NODE_ENV !== 'production') {
    // 设置代理,将 vm 实例上的属性代理到 vm._renderProxy
      initProxy(vm);
    } else {
      vm._renderProxy = vm;
    }
    // expose real self
    vm._self = vm;
  // 初始化组件实例关系属性,比如 $parent、$children、$root、$refs 等
    initLifecycle(vm);
   /**
     * 初始化自定义事件,这里需要注意一点,所以我们在 <comp @click="handleClick" /> 上注册的事件,监听者不是父组件,
     * 而是子组件本身,也就是说事件的派发和监听者都是子组件本身,和父组件无关
     */
    initEvents(vm);
 // 解析组件的插槽信息,得到 vm.$slot,处理渲染函数,得到 vm.$createElement 方法,即 h 函数
    initRender(vm);
// 调用 beforeCreate 钩子函数
    callHook(vm, 'beforeCreate');
// 初始化组件的 inject 配置项,得到 result[key] = val 形式的配置对象,然后对结果数据进行响应式处理,并代理每个 key 到 vm 实例
    initInjections(vm); // resolve injections before data/props
// 数据响应式的重点,处理 props、methods、data、computed、watch
    initState(vm);
/ /解析组件配置项上的 provide 对象,将其挂载到 vm._provided 属性上
    initProvide(vm); // resolve provide after data/props
// 调用 created 钩子函数
    callHook(vm, 'created');

    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
      vm._name = formatComponentName(vm, false);
      mark(endTag);
      measure(("vue "   (vm._name)   " init"), startTag, endTag);
    }
// 如果发现配置项上有 el 选项,则自动调用 $mount 方法,也就是说有了 el 选项,就不需要再手动调用 $mount,反之,没有 el 则必须手动调用 $mount
    if (vm.$options.el) {
      vm.$mount(vm.$options.el);
    }
  };
}

● 处理组件配置项 ○ 初始化根组件时进行了选项合并操作,将全局配置合并到根组件的局部配置上 ○ 初始化每个子组件时做了一些性能优化,将组件配置对象上的一些深层次属性放到 vm.options 选项中,以提高代码的执行效率 ● 初始化组件实例的关系属性,比如 parent、children、root、refs 等 ● 处理自定义事件 ● 调用 beforeCreate 钩子函数 ● 初始化组件的 inject 配置项,得到 ret[key] = val 形式的配置对象,然后对该配置对象进行浅层的响应式处理(只处理了对象第一层数据),并代理每个 key 到 vm 实例上 ● 数据响应式,处理 props、methods、data、computed、watch 等选项 ● 解析组件配置项上的 provide 对象,将其挂载到 vm._provided 属性上 ● 调用 created 钩子函数 ● 如果发现配置项上有 el 选项,则自动调用 mount 方法,也就是说有了 el 选项,就不需要再手动调用 mount 方法,反之,没提供 el 选项则必须调用 mount ● 接下来则进入挂载阶段

0 人点赞