Vue源碼解析-Vue和實例對象

先看一下源碼中關(guān)于Vue函數(shù)的定義(稍稍簡化),摘自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); // 調(diào)用Vue.prototype._init函數(shù), this指向的就是Vue實例對象了
  }

  //調(diào)用一系列方法
  initMixin(Vue);   // 初始化,調(diào)用initMixin函數(shù),傳入Vue構(gòu)造函數(shù)
  stateMixin(Vue);
  eventsMixin(Vue);
  lifecycleMixin(Vue);
  renderMixin(Vue);

 function initMixin (Vue) {
    Vue.prototype._init = function (options) {
      var vm = this; // vm被賦值為實例對象
      vm._uid = uid$3++;  //  當(dāng)觸發(fā)init方法,新建Vue實例時(當(dāng)渲染組件時也會觸發(fā))uid都會遞增

      // 加入標(biāo)志防止該對象對observer監(jiān)聽
      vm._isVue = true;
      // 合并options
      if (options && options._isComponent) {  // 當(dāng)是組件時
        // 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 {     // 當(dāng)不是組件時
       // 將合并后的options賦值給實例對象的$options
        vm.$options = mergeOptions(
          resolveConstructorOptions(vm.constructor),
          options || {},
          vm
        );
      }
     
      initProxy(vm);
      // 實例對象的_self指向自己, 暴露出去
      // 各種初始化
      initLifecycle(vm); 
      initEvents(vm);
      initRender(vm);
      callHook(vm, 'beforeCreate'); // 觸發(fā)beforeCreate生命周期函數(shù)
      initInjections(vm); // resolve injections before data/props
      initState(vm);
      initProvide(vm); // resolve provide after data/props
      callHook(vm, 'created'); // 觸發(fā)created生命周期函數(shù)

      // 掛載el
      if (vm.$options.el) {
        vm.$mount(vm.$options.el);
      }
    };
  }

看看

Vue就是一個函數(shù),當(dāng)然可以把它理解為構(gòu)造函數(shù)和類,她只能用new 來生成實例對象。

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

var vm = new Vue({
      el: '#app',
      data: {
          showA: false
      },
      beforeCreate(){
      },
      created(){
      },
       mounted(){
       },
       methods: {
       }
});
// 可以打印出如下的數(shù)據(jù)
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函數(shù)最重要的兩個部分就是:

1.初始化各種狀態(tài),然后調(diào)用beforeCreatedcreated 生命周期函數(shù)。
2.合并options生成 $options, 然后掛載。

看看$options的由來:

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

resolveConstructorOptions函數(shù)生成的對象含有:components,directives, filters
然后再進行合并:
最后得出的$options,含有:

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

然后去調(diào)用$amount函數(shù),執(zhí)行掛載。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容