Vue初始化過程


  用vue也有一兩年了,始終對vue一知半解,不怎么了解內部的執行過程,最近在看vue源碼,還是不少收獲的,其中不乏瀏覽器事件輪詢機制、閉包、設計模式等,還是非常值得一讀。本篇簡要記錄下vue的初始化過程,具體初始化過程及內容的時序如下圖所示:

  

  初始化主要執行了vue-dev\src\core\index.js和vue-dev\src\core\instance\index.js兩個文件,具體執行代碼如下:

  vue-dev\src\core\instance\index.js

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)
}
// 初始化vue _init方法
initMixin(Vue)
// 初始化data, prop watch等
stateMixin(Vue)
// 初始化發布-訂閱事件模型
eventsMixin(Vue)
// 初始化組件生命周期鈎子
lifecycleMixin(Vue)
// 初始化nextTick, render
renderMixin(Vue)

  vue-dev\src\core\index.js

initGlobalAPI(Vue)

Object.defineProperty(Vue.prototype, '$isServer', {
  get: isServerRendering
})

Object.defineProperty(Vue.prototype, '$ssrContext', {
  get () {
    /* istanbul ignore next */
    return this.$vnode && this.$vnode.ssrContext
  }
})

// expose FunctionalRenderContext for ssr runtime helper installation
Object.defineProperty(Vue, 'FunctionalRenderContext', {
  value: FunctionalRenderContext
})

Vue.version = '__VERSION__'

  在方法initGlobalAPI中,會初始化一切Vue全局的工具方法,像我們常用的全局注冊組件Vue.components,全局注冊指令Vue.directives,set/delete等,具體代碼如下所示:

export function initGlobalAPI (Vue: GlobalAPI) {
  // config
  const configDef = {}
  configDef.get = () => config
  if (process.env.NODE_ENV !== 'production') {
    configDef.set = () => {
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      )
    }
  }
  Object.defineProperty(Vue, 'config', configDef)

  // exposed util methods.
  // NOTE: these are not considered part of the public API - avoid relying on
  // them unless you are aware of the risk.
  Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }

  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  // 2.6 explicit observable API
  Vue.observable = <T>(obj: T): T => {
    observe(obj)
    return obj
  }
  // 初始化Vue構造函數的options,初始屬性為components,directives,filters
  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
  })

  // this is used to identify the "base" constructor to extend all plain-object
  // components with in Weex's multi-instance scenarios.
  // _base屬性
  Vue.options._base = Vue

  extend(Vue.options.components, builtInComponents)
  // 初始化vue.use api
  initUse(Vue)
  // 初始化mixins api
  initMixin(Vue)
  // 初始化extend api
  initExtend(Vue)
  // 初始化component,directive,filter
  initAssetRegisters(Vue)
}

  在首次項目初始化的過程中,會初始化幾個Vue的私有方法,后面在實例化Vue的時候,會經常用到,比如Vue實例上會掛載_init方法,在我們實例化Vue的過程中,實際上調用的是this._init方法,接收的參數options就是我們初始化時的配置項。_render方法是在我們掛載DOM時會被調用,之后會調用_update方法,每次DOM的初始化、更新,都會執行_update方法。

  以上為vue初始化過程,主要就是為vue的實例化做一些前置的准備工作,下一篇會介紹vue的實例化過程,如何從基本的配置項到掛載到DOM


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM