Disclaimer: The English annotation is the original work of You Yuxi, and the Chinese translation is my understanding. If the level is limited, please take the original work as the standard, hope correct, forgive me ha ~

If you think it’s good, give me a star, and hurry up here on Github

The origins of the Vue project actually came from instantiating the Vue:

new Vue({ el: ... , data: ... . })Copy the code

So what exactly is happening during this instantiation? Let’s find out. Open the Vue source file, its core code in the SRC /core directory. Here we start with the entry file index.js:

// This should be instantiated import Vue from'./instance/index'// This should initialize some global API import {initGlobalAPI} from'./global-api/index'// This should be a Boolea import {isServerRendering} from to determine whether the introduction is an SSR environment'core/util/env'Import {FunctionalRenderContext} from virtualDom'core/vdom/create-functional-component'// Initialize the global variable initGlobalAPI(Vue) // define attributes for the Vue prototype$isServer
Object.defineProperty(Vue.prototype, '$isServer', {get: isServerRendering}) // Define attributes for the Vue prototype$ssrContext
Object.defineProperty(Vue.prototype, '$ssrContext', {
  get () {
    /* istanbul ignore next */
    return this.$vnode && this.$vnode.ssrContext}}) // Define the FunctionalRenderContext method // expose for vUE prototypes when running for SSR environmentsfor ssr runtime helper installation
Object.defineProperty(Vue, 'FunctionalRenderContext', {
  value: FunctionalRenderContext
})

Vue.version = '__VERSION__'/ / export Vueexport default Vue
Copy the code

Let’s take a look at each load file:

import Vue from './instance/index'
Copy the code

As follows:

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '.. /util/index'

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)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue
Copy the code

Here we define a simple Vue Class, and then call a series of init, mixin and other methods to initialize some functions. We will analyze the details later, but through the code we can confirm: yes! Here we do export a Vue functionality class.

import { initGlobalAPI } from './global-api/index'
Copy the code

The initGlobalAPI, which can be found on the Vue website, explains the global properties of the Vue:

import config from '.. /config'
import { initUse } from './use'
import { initMixin } from './mixin'
import { initExtend } from './extend'
import { initAssetRegisters } from './assets'
import { set, del } from '.. /observer/index'
import { ASSET_TYPES } from 'shared/constants'
import builtInComponents from '.. /components/index'

import {
  warn,
  extend,
  nextTick,
  mergeOptions,
  defineReactive
} from '.. /util/index'

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) // These tool methods are not considered part of the global API, so don't rely on them unless you've exposed util methods. 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} // Define the global attribute vue.set = hereset
  Vue.delete = del
  Vue.nextTick = nextTick

  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. Vue.options._base = Vue extend(Vue.options.components, BuiltInComponents) // Define the global method initUse(Vue) initMixin(Vue) initExtend(Vue) initAssetRegisters(Vue)}Copy the code

♦ vue. config Global configuration items

♦ Vue.util: various utility functions, as well as some compatibility flags. ♦ Vue.set/delete: This should be seen in your documentation

♦ [vue.nexttick] This is an optimization done by merging data changes before the next update

♦ [vue. options] This option is different from the one we used to construct the instance above. This is the resource (component directive filter) that Vue provides by default.

♦ [vue. use] Defined by the initUse method

♦ vue. mixin is defined by the initMixin method

♦ vue. extend is defined by the initExtend method

import { isServerRendering } from 'core/util/env'
Copy the code
// This needs to be lazy-evaled because vue may be required before SSR needs to be set to VUE_ENV (vUE environment)'server'
// vue-server-renderer can set VUE_ENV
let _isServer
export const isServerRendering = () => {
  if (_isServer === undefined) {
    /* istanbul ignore if* /if (!inBrowser && !inWeex && typeof global ! = ='undefined') {
      // detect presence of vue-server-renderer and avoid
      // Webpack shimming the process
      _isServer = global['process'].env.VUE_ENV === 'server'
    } else {
      _isServer = false}}return _isServer
}
Copy the code
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
Copy the code
export functionFunctionalRenderContext ( data: VNodeData, props: Object, children: ? Array<VNode>, parent: Component, Ctor: Class<Component>) {const options = ctor. options // Ensure the createElement method is in the components methodfunction inFunctional Components // gets a unique context - this is necessaryfor correct named slot check
  let contextVm
  if (hasOwn(parent, '_uid') {// no contextVm = object.create (parent) //$flow-disable-line
    contextVm._original = parent
  } else {
    // the context vm passed in is a functional context as well.
    // in this case we want to make sure we are able to get a hold to the
    // real context instance.
    contextVm = parent
    // $flow-disable-line parent = parent._original } const isCompiled = isTrue(options._compiled) const needNormalization = ! isCompiled this.data = data this.props = props this.children = children this.parent = parent this.listeners = data.on ||  emptyObject this.injections = resolveInject(options.inject, parent) this.slots = () => resolveSlots(children, Parent) // support the method to compile templatefor compiled functional template
  if (isCompiled) {
    // exposing $options for renderStatic()
    this.$options = options
    // pre-resolve slots for renderSlot()
    this.$slots = this.slots()
    this.$scopedSlots = data.scopedSlots || emptyObject
  }

  if (options._scopeId) {
    this._c = (a, b, c, d) => {
      const vnode = createElement(contextVm, a, b, c, d, needNormalization)
      if(vnode && ! Array.isArray(vnode)) { vnode.fnScopeId = options._scopeId vnode.fnContext = parent }return vnode
    }
  } else {
    this._c = (a, b, c, d) => createElement(contextVm, a, b, c, d, needNormalization)
  }
}

installRenderHelpers(FunctionalRenderContext.prototype)
Copy the code

At this point, our entry file is almost clear. Next, let’s take a look at the implementation of the Vue class, where we will learn about the Vue lifecycle.

Thanks muwoo for the material