美文网首页
Vue源码解析-Vue和实例对象

Vue源码解析-Vue和实例对象

作者: kruz | 来源:发表于2020-03-05 11:06 被阅读0次

    先看一下源码中关于Vue函数的定义(稍稍简化),摘自Vue 2.6.11。

     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函数, this指向的就是Vue实例对象了
      }
    
      //调用一系列方法
      initMixin(Vue);   // 初始化,调用initMixin函数,传入Vue构造函数
      stateMixin(Vue);
      eventsMixin(Vue);
      lifecycleMixin(Vue);
      renderMixin(Vue);
    
     function initMixin (Vue) {
        Vue.prototype._init = function (options) {
          var vm = this; // vm被赋值为实例对象
          vm._uid = uid$3++;  //  当触发init方法,新建Vue实例时(当渲染组件时也会触发)uid都会递增
    
          // 加入标志防止该对象对observer监听
          vm._isVue = true;
          // 合并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 {     // 当不是组件时
           // 将合并后的options赋值給实例对象的$options
            vm.$options = mergeOptions(
              resolveConstructorOptions(vm.constructor),
              options || {},
              vm
            );
          }
         
          initProxy(vm);
          // 实例对象的_self指向自己, 暴露出去
          // 各种初始化
          initLifecycle(vm); 
          initEvents(vm);
          initRender(vm);
          callHook(vm, 'beforeCreate'); // 触发beforeCreate生命周期函数
          initInjections(vm); // resolve injections before data/props
          initState(vm);
          initProvide(vm); // resolve provide after data/props
          callHook(vm, 'created'); // 触发created生命周期函数
    
          // 挂载el
          if (vm.$options.el) {
            vm.$mount(vm.$options.el);
          }
        };
      }
    
    

    看看

    Vue就是一个函数,当然可以把它理解为构造函数和类,她只能用new 来生成实例对象。

    我们平常使用引入Vue的方式就是:

    var vm = new Vue({
          el: '#app',
          data: {
              showA: false
          },
          beforeCreate(){
          },
          created(){
          },
           mounted(){
           },
           methods: {
           }
    });
    // 可以打印出如下的数据
    console.log(vm instanceof Vue); // true;   
    console.log(vm._self === vm); // true;
    console.log(vm._isVue); // true;
    console.log(vm._uid ); // 0; // 只有一个实例且没有组件就是0
    console.log(vm.$options); //  生成后的options
    

    _init函数最重要的两个部分就是:

    1.初始化各种状态,然后调用beforeCreatedcreated 生命周期函数。
    2.合并options生成 $options, 然后挂载。

    看看$options的由来:

     vm.$options = mergeOptions(
              resolveConstructorOptions(vm.constructor),
              options || {},
              vm
    );
    

    resolveConstructorOptions函数生成的对象含有:components,directives, filters
    然后再进行合并:
    最后得出的$options,含有:

    {
      components: {}
      directives: {}
      filters: {}
      _base: ƒ Vue(options)
      el: "#app"
      data: ƒ mergedInstanceDataFn()
      mounted: [ƒ]
      methods: { beforeEnter: ƒ, enter: ƒ, leave: ƒ, changeShow: ƒ}
      render: ƒ anonymous( )
      staticRenderFns: []
    }
    

    然后去调用$amount函数,执行挂载。

    相关文章

      网友评论

          本文标题:Vue源码解析-Vue和实例对象

          本文链接:https://www.haomeiwen.com/subject/lyjtrhtx.html