I also wrote an interpretation of the life cycle of VUE2 before. This time, I will recall it again according to this book to deepen my impression.

(1) At first, new Vue() is called, and init() is executed in new Vue() to start the initialization of Vue, as shown in the figure below:

(2) Init functions include executing a series of functions, as shown in the figure:

Including mount after vue instance is created:

Will be (3) and then call the mount to mountComponent function, beforeMount, mounted, beforeUpdate hooks are in mountComponent function, mainly as follows:

export function mountComponent (vm: Component, el: ? Element, hydrating? : boolean) :Component {
    vm.$el = el
    // Some warnings and judgments
    if(! vm.$options.render) { }// Execute beforeMount hook function
    callHook(vm, 'beforeMount')

    let updateComponent
    // Rerender the component's callback function
    updateComponent = () = > {
      vm._update(vm._render(), hydrating)
    }
    // Use Watcher to listen on the VM and perform the updateComponent callback if the state changes
    new Watcher(vm, updateComponent, noop, {
        // Execute the beforeUpdate callback before executing the callback
        before () {
            callHook(vm, 'beforeUpdate')}},true)
    // Execute the mounted hook function after rendering
    if (vm.$vnode == null) {
        vm._isMounted = true
        callHook(vm, 'mounted')}return vm
}
Copy the code

In fact, the whole life cycle, from the source code, I think is a series of initialization functions and hooks.

So let’s look at it from top to bottom:

A, initLifecycle

Initialize some properties and default values, such as its parent(find the parent of its first non-abstract type), its children, and its root.

Second, the initEvents

The event initialized here is the parent component using V-on in the template to listen for emit events in the child component.

All registered events are stored in vm._events, and the core function is updateComponentListeners()

Third, initRender

InitRender primarily prepares the vue render for initialization and also initializes some properties, most importantly the creatElement() function mounted to vue _c in preparation for later creation of the virtual DOM using createElement

The hook function beforeCreate is then triggered

InitInjections // resolve before data/props

Internally initialize Inject by resolveInject

Inject: Use inject along with provide for ancestors to inject a dependency into descendants. Ancestor components provide dependencies through provide, and descendant components inject dependencies through inject.

By the way, do you see the note in the title? Inject is initialized before data/props, while provide is initialized after data/props, which is why use initInjections first, then initState, then initProvide.

Fifth, initState

This function is more complicated, it contains a lot of initialization, in general, contains initProps, initMethods, initData, initComputed, initWatch, actually this order is to have cultured. To initialize props, use props in data. To initialize props and data, observe them in Watch.

InitProvide // resolve provide after data/props

Assign the value of provide in vm.options to vm

vm._provided = vm.$options.provide

Then you call the created hook function, and you can use props, methods, data,computed,watch, and this is where I usually call the API in my projects, because data is already responsive

Seven, vm. $mount

After calling the Created hook function, the following code is executed

    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
Copy the code

The mount method comes in two versions, runtime only and runtime+compile. Templates are compileToFunctions. Compile to the render function and return to the mountComponent after compiling.

Eight, mountComponent

The beforeMount hook function is called directly after some judgment is made within the function. BeforeMount actually compiles the template to Render

Then put the VM into Watcher and put updateComponent as a callback function, and if the state returns a change, the beforeUpdate callback is executed before the change. If it’s the first render, you’ll definitely perform render to generate the virtual DOM and then generate the view.

The code is as follows:

    new Watcher(vm, updateComponent, noop, {
    before () {
      if(vm._isMounted && ! vm._isDestroyed) { callHook(vm,'beforeUpdate')}}},true /* isRenderWatcher */)
Copy the code

Mounted is called when the render or update is complete.

The code is as follows:

if (vm.$vnode == null) {
    vm._isMounted = true
    callHook(vm, 'mounted')}Copy the code

The creat, mount, and update lifecycle. this is the end of the creat, mount, and update lifecycle.

Others include:

Activated: activated when a component cached by keep-alive is activated.

Deactivated: activated when a component cached by keep-alive is deactivated.

BeforeDestory: called before instance destruction. At this step, the instance is still fully available.

Destroyed: Called after the instance is destroyed. When this hook is called, all instructions for the Vue instance are unbound, all event listeners are removed, and all subinstances are destroyed.

ErrorCaptured: Called when you catch an error from a descendant component. (vue2.5 + new)