This article gives a brief overview of what vue does in the first rendering process. More reference

The running process of Vue

Templates ({{}} syntax) -- > AST (Abstract syntax tree) -- > F (x) (rendering function) -- > Virtual Dom -- > Dom (diff algorithm)Copy the code

Vue initialization

Import Vue from ‘Vue’ import Vue from main.js import Vue from ‘Vue’ import Vue from ‘Vue’ import Vue However, we generally use Vue/CLI with vue-loader for parsing. Vue files are H functions, so the complete version with compiler is not required

  • The full and runtime versions differ
    • The difference between the full version and the runtime version is that the full version has an extra compiler, one bigger than the runtime version. Therefore, it is generally simple to introduce the full version with the compiler in demo, while the vue/ CLI used with the Webpack tool is used without the compiler, because it is used with vue-loader. Vue-loader also contains vue-template-compiler, which can convert. Vue files into H functions
  • Vue pack the dist folder in different versions mainly parse:
    • Universal version (UMD): full version vue.js and runtime version vue.runtime.js

    • Comnonjs versions: the full vue.common.js and the runtime version vue.runtime.common.js

    • ESModule versions: full version vue.esm.js and runtime version vue.runtime.esm.js

Vue class lookup (SRC/core/instace/index. Js)

Vue file loading order, according to the complete version of entry-runtime-with-compiler.js, different entry will generate different files:

// Execute flow 1234
// The vue class can be found on 4321
src/core/instace/index.js ===> 1
src/core/index.js ===> 2
src/platforms/web/runtime/index.js ===> 3
src/platforms/web/entry-runtime-with-compiler.js 4
Copy the code
  • SRC/core/instace/index. Js main content:

    • Define vue constructors and initialize instance properties and instance methods of Vue. Prototype. Add methods and properties under vue. The total method is shown as follows:

    • InitMixin method: Mount the _init method on the vue prototype, mainly to initialize the Options object

    • StateMixin: add $data and $props, $set and $delete and $watch to the vue prototype

    • EventsMixin method: Add $ON, $once, $off and $emit methods to the vue prototype

    • LifecycleMixin method: Added _update (which mainly calls __Patch__ to update the DOM by comparing old and new nodes), $forceUpdate and $destory methods to the vue prototype

    • RenderMixin methods: Add $nextTick and _render methods to the vue prototype (this method executes the render function passed in by the user or compiled, and generates vNodes)

  • SRC /core/index.js

    • InitGlobalAPI methods: initializes many vUE static methods and properties (nextTick,del,set, etc.)
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.')}}// Add a config attribute
  Object.defineProperty(Vue, 'config', configDef)
  // add a static member util
  Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }
  // Add 3 static members set delete nextTick
  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick
  // Add a static member observable
  Vue.observable = <T>(obj: T): T => {observe(obj) return obj} // Options are initialized</T>
  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type= > {
    Vue.options[type + 's'] = Object.create(null)
  })
  Vue.options._base = Vue
  Keep-alive builtInComponents // register a global keep-alive builtInComponents component export
  extend(Vue.options.components, builtInComponents)
  Use () vue.mixin () vue.extend ()
  initUse(Vue)
  initMixin(Vue)
  initExtend(Vue)
  // Initialize vue.directive (), Vue.component(), vue.filter()
  initAssetRegisters(Vue)
}
Copy the code
  • src/platforms/web/runtime/index.js

    • New __Patch__ method, which is mainly used for diff comparison between the old node and the new node, and then update dom operation

    • Add a $mount method that converts the render function into a virtual DOM

  • src/platforms/web/entry-runtime-with-compiler.js

    • The main effect is to rewrite the $mount method under the Vue prototype. If there is no render function, it will look for the tempalte attribute, and the tempalte attribute will be used by the compiler to edit the template. The pre-rewrite mount method is only available to the render function.

Vue initialization summary

All of the above operations are what we did when we introduced vue, i.e. import vue from ‘vue’. After executing this line of code, we continue to execute the contents of the main.js file and call the vue constructor.

new Vue({
    router,
    store,
    render: h= >h(App)
}).$mount('#app')
Copy the code

The _init method is primarily executed, and from here, the vUE lifecycle begins._initThe main functions of the method are shown below, please refer to the source code for more: Life hook:

  • BeforeCreate hook: Prior to this lifecycle hook, the main things vUE does are adding properties and methods to the VUE prototype, adding static properties and methods to the VUE, and adding properties and methods to the VM instance.
  • Created a hook(Data,methods and other attributes can be obtained) : After beforeCreated is done, three methods are executed: initInjections,initState, initProvide, which focuses onInitState method, in which the vm instance’s$props,$data,$methods,comouted,watchEtc, and calls an initData() method, which calls the Observer() method to convert the data in data to responsive data. So before the Created life cycle, the VM’s$dataProperties are initialized, so we can call properties in data and props or methods in Created.
    Inject inject into the VM instance
    callHook(vm, 'beforeCreate')
    Inject inject into the VM instance
    initInjections(vm)
    // Initialize $props,$methods,$data,computed,watch for the VM
    initState(vm)
    // Inject provide into the VM instance
    initProvide(vm)
    // Implement the Created lifecycle
    callHook(vm, 'created')
    Copy the code
  • When the Created life cycle is complete, thevm.$options.elDetermines whether the current EL is passed in, i.e
newVue ({el:'#app',
   route,
   ...
})
Copy the code

The EL attribute of. If el exists, proceed with $mount. If it doesn’t exist, it doesn’t go down, and for the code to go down, it must execute the $mount method. But users can use the new Vue({… }).$mount(‘#app’) to call $mount on the vue instance out of new.

  • $mount function“, either passing in el when new or calling it after instance$mount()It’s all execution$mountFunction.
    • The use of$mount()That’s the mount method that we rewrote. The render mount method can only be used with the render attribute on the new vue. The vue instance passed without the render attribute will look for the template attribute.template->renderIf the dom specified by el is used as a template, the DOM under EL is assigned to template, i.eel=>template=>render). soThe mount function finds the template priority: render>template>el.$mountThe ultimate goal is to convert to the render function and mount it under the options.render property. After converting to the render function, the render function is finally executed$mount. The mount function is used to render the render function and convert the render function into a virtual DOM.
    • Extension: Three ways to get the render function
      • The user passes in render itself
        new Vue({
            router,
            store,
            render: h= >{
                h('div', {class: 'vdom'},[
                    h('p'['aaa'])
                ])
            }
        }).$mount('#app')
        Copy the code
      • Vue files are compiled into render functions, usually parsed into render functions with vue-template-compiler of vue-Loader.
        new Vue({
            router,
            store,
            render: h= >h(App)
        }).$mount('#app')
        Copy the code
      • The template template is compiled into render
      new Vue({
          router,
          store,
          template: '
                
      hahaha
      '
      }).$mount('#app') Copy the code
  • beforeMountLifecycle hooks (** to get render function **)
    • The hook function is in the mountComponnet function of the return in the mount function overridden before.

    • The mountComponnet function does four things.

      • The beforeMount hook is executed, so we initialize and get the render function before beforeMount. BeforeMount starts the render function to render the virtual DOM and then updates the real DOM.
      • UpdateComponent function.This function performs the _update method._updateThe first argument to the method isvm._render()The virtual DOM is the result of method execution._renderThe render function internally renders a virtual DOM, which returns a VNode

        _updateThe inside of the method is shown,Mainly implemented__patch__Method Compare the old and new VNodes to find out the differences and update the real DOM. For the first rendering, the current VNode is generated directly into the real DOM.

      Conclusion: The _update method executed by updateComponent calls __Patch__ to compare the old and new VNodes and generate a real DOM. The updateComponent method is used to render the render function, update the DOM, and return the real DOM.
      • New Watcher, new An instance of Wacther is passed the updateComponent function as an argument. Then execute the Watcher constructor as shown. There are three types of Watcher, rendering Watcher,
        w a t c h Function of the w a t c h e r . c o m p u t e d the w a t c h e r . What we’re doing here is rendering the page w a t c h e r . And this renders the page w a t c h e r Is the main v u e The instance w a t c h e r Can be interpreted as the entire page w a c t h e r . You can see that we passed in to W a t c h e r Instance parameter of u p d a t e C o m p o n e n t methods ( Apply colours to a drawing r e n d e r Function and trigger virtual d o m Update the real d o m , return to reality d o m ) In the end by the g e t ( ) Method fires, and finally assigns to t i s . v a l u e . while t h i s . v a l u e It will eventually be used to update the dependent. When we call t h i s . Watcher for the watch function, watcher for computed. Here we render the page is render Watcher. The watcher for the rendered page is the watcher for the main vue instance, which can be understood as the wacther for the entire page. You can see that the updateComponent method we passed to the Watcher instance parameter (render the render function, trigger the virtual DOM to update the real DOM, and return the real DOM) is finally triggered by the get() method, Value is assigned to tis. Value, and this.value is used to update the dependent. When we call this.
        When foceUpdate(), the update method of this instance is triggered, updating the entire page. UpdateComponent is automatically called once for new Wacher, so that’s our first render.

      • Mounted hook function. After executing New Wacther, the code continues to execute, as illustrated. Verify that the current VNode is null. If null, the virtual DOM has not been generated before, that is, the first rendering. In this case, set vm._isMounted to True. And executes the Mounted hook function. The first rendering is now complete.
  • Mounted Life cycle hook

BeforeMount to Mounted does the following tasks:

  • Render the render function into the virtual DOM
  • Execute the vm._update function to convert the virtual DOM to the real DOM

If it is between beforeUpdate and Update hooks, it is not the first rendering and the virtual DOM will have both old and new. The vm._update function is used to compare the old and new vNodes to find out the differences and update the areas that need to be updated.

Refer to the article

Brief introduction to the whole process of vUE first rendering