Vue learning series - understanding life cycle and hook

Posted by dev99 on Sun, 03 Nov 2019 12:40:42 +0100

Preface

In Last article In, we have classified and explained the common instructions encountered in the development of vue. We have probably learned how to realize data binding and realize dynamic data display function. With instructions, we can develop faster and better. In this article, we will explore the life cycle of vue through examples.

All things have spirits. All things in the world have souls. From mountains, rivers, lakes, seas, flowers, trees, ants to humans, all animals and plants, to the stars and the universe on earth, they all have souls. We can say that they all have lives, but their life forms are beyond our understanding. In production, the life cycle is generally speaking the whole process from the nature to the nature, that is, the process from the design of collection materials to the circulation and use after processing and production, as well as the process of product scrapping and then returning to the nature. The whole process is a complete life cycle. Therefore, in the development of application projects, from the loading of startup pages, page rendering to destruction, it is also a life cycle. Vue divides the whole life cycle into creation, mount, update, destruction and other stages. Each stage will give us some "hooks" to do some actions we want to achieve. The "hook" here can be understood as follows: hook at each stage and respond.  

          

 

Learning life cycle enables us to better understand the life mechanism of Vue. By understanding the hooks of each stage, we can better realize our business code and handle more complex business logic.

Content

Every component of Vue has its own life cycle, which includes creating, initializing data, compiling templates, mounting Dom, rendering → updating → rendering, unloading, etc.

In the whole life cycle, it is divided into 8 stages: before / after creation, before / after loading, before / after updating, before / after destroying.

Execution sequence

* image from Official website As long as you understand this diagram, you will have a general understanding of Vue's life cycle.

When talking about the life cycle of Vue, we first need to create an instance:

Start

I. before / after creation:

1. Before create: before instance creation: the data and methods of the instance in this stage are unreadable (el and data are not initialized)

  var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      },
       beforeCreate: function () {
                console.group('beforeCreate Component just created,Status before component property calculation===============>');
               console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
               console.log("%c%s", "color:red","data   : " + this.$data); //undefined 
               console.log("%c%s", "color:red","message: " + this.message)  //undefined
        },
})

2.created - creation completed: after instance creation: Data observer, property and method operations, and watch/event event callback have been completed in this stage. mount has not started yet, the $el attribute is not visible at present, and the data has not been rendered on DOM elements (initialization of data data has been completed, el has not)

 var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      },
        created: function () {
            console.group('created Component creation completed,Property is bound but dom Status not yet generated===============>');
            console.log("%c%s", "color:red","el     : " + this.$el); //undefined
               console.log("%c%s", "color:red","data   : " + this.$data); //Initialized 
               console.log("%c%s", "color:red","message: " + this.message); //Initialized
        },
})

II. Before / after loading

1.beforeMount: ready to load -- called before mount begins: the first time the associated render function is called. The program runs, and the console looks at the output (the virtual el and data initialization are completed)

  var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      }, 
        beforeMount: function () {
            console.group('beforeMount Status of template before mounting===============>');
            console.log("%c%s", "color:red","el     : " + (this.$el)); //Initialized
            console.log(this.$el);
               console.log("%c%s", "color:red","data   : " + this.$data); //Initialized  
               console.log("%c%s", "color:red","message: " + this.message); //Initialized  
        },
})

2.mounted: Mount completion - the El option's DOM node is replaced by the newly created vm.$el, and is mounted on the instance to invoke the life cycle function. At this time, the instance data is rendered on the DOM node (the real el and data initialization are completed)

var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      },
        mounted: function () {
            console.group('mounted Template mount end status===============>');
            console.log("%c%s", "color:red","el     : " + this.$el); //Initialized
            console.log(this.$el);    
               console.log("%c%s", "color:red","data   : " + this.$data); //Initialized
               console.log("%c%s", "color:red","message: " + this.message); //Initialized 
        },
})

 

 

At this time, the four stages of page rendering have been completed. Let's take a look at the process: (in the beforeCreate stage at the beginning, neither the data nor the page are rendered, but the static data of the page has been loaded out, and then step by step, first the vue instance, then the mount, and finally the page rendering is completed)

III. before / after update

1.beforeUpdate: before Data update - called when Data is updated, but DOM is not re rendered. Before DOM is not rendered when Data is updated, state processing can be performed in this life function

When modifying the data of the vue instance, vue will automatically help us update the rendered view. In this process, vue provides us with a hook for before update. When we detect that we want to modify the data, the hook for before update will be triggered before updating the rendered view.

  var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      },
        beforeUpdate: function () {
            console.group('beforeUpdate Status before update===============>');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);   
               console.log("%c%s", "color:red","data   : " + this.$data); 
               console.log("%c%s", "color:red","message: " + this.message); 
        },
})

Console input app.message = 'AI Sanyuan'

According to the figure, our Data has been updated, but the page has not been updated

2.update: in this state, the data is updated and the DOM is re rendered. When the lifecycle function is called, the component DOM has been updated, so you can now perform DOM dependent operations. Updated will execute every time the instance updates the data

 var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      }, 
        updated: function () {
            console.group('updated Update completion status===============>');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el); 
               console.log("%c%s", "color:red","data   : " + this.$data); 
               console.log("%c%s", "color:red","message: " + this.message);
        },
})

IV. before / after destruction

1.beforeDestroy: before the page is destroyed, it is called before the instance is destroyed. Calling the destroy() method of the instance can destroy the current component. Before destroying, the beforedestroy hook will be triggered.

  var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      },
        beforeDestroy: function () {
            console.group('beforeDestroy Status before destruction===============>');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);    
               console.log("%c%s", "color:red","data   : " + this.$data); 
               console.log("%c%s", "color:red","message: " + this.message); 
        },
})

Console input app.$destroy()

2.destroyed: destruction completed - Vue instance destroyed after the call. After the call, everything indicated by the Vue instance is unbound, all event listeners are removed, and all child instances are destroyed.

var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      },
        destroyed: function () {
            console.group('destroyed Destruction completion status===============>');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);  
               console.log("%c%s", "color:red","data   : " + this.$data); 
               console.log("%c%s", "color:red","message: " + this.message)
        }
})

 

At this time, we can see that after the vue instance is destroyed, the DOM of the page can no longer be modified by modifying the Data page.

Source code

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>
</head>
<body>

<div id="app">
     <p>{{ message }}</p>
</div>

<script type="text/javascript">
    
  var app = new Vue({
      el: '#app',
      data: {
          message : "This is AI Sanyuan's homepage" 
      },
        beforeCreate: function () {
           console.group('beforeCreate Component just created,Status before component property calculation===============>');
           console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
           console.log("%c%s", "color:red","data   : " + this.$data); //undefined 
           console.log("%c%s", "color:red","message: " + this.message)  //undefined
        },
        created: function () {
           console.group('created Component creation completed,Property is bound but dom Status not yet generated===============>');
           console.log("%c%s", "color:red","el     : " + this.$el); //undefined
           console.log("%c%s", "color:red","data   : " + this.$data); //Initialized 
           console.log("%c%s", "color:red","message: " + this.message); //Initialized
        },
        beforeMount: function () {
           console.group('beforeMount Status of template before mounting===============>');
           console.log("%c%s", "color:red","el     : " + (this.$el)); //Initialized
           console.log(this.$el);
           console.log("%c%s", "color:red","data   : " + this.$data); //Initialized  
           console.log("%c%s", "color:red","message: " + this.message); //Initialized  
        },
        mounted: function () {
            console.group('mounted Template mount end status===============>');
            console.log("%c%s", "color:red","el     : " + this.$el); //Initialized
            console.log(this.$el);    
            console.log("%c%s", "color:red","data   : " + this.$data); //Initialized
            console.log("%c%s", "color:red","message: " + this.message); //Initialized 
        },
        beforeUpdate: function () {
            console.group('beforeUpdate Status before update===============>');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);   
            console.log("%c%s", "color:red","data   : " + this.$data); 
            console.log("%c%s", "color:red","message: " + this.message); 
        },
        updated: function () {
            console.group('updated Update completion status===============>');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el); 
            console.log("%c%s", "color:red","data   : " + this.$data); 
            console.log("%c%s", "color:red","message: " + this.message);
        },
        beforeDestroy: function () {
            console.group('beforeDestroy Status before destruction===============>');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);    
            console.log("%c%s", "color:red","data   : " + this.$data); 
            console.log("%c%s", "color:red","message: " + this.message); 
        },
        destroyed: function () {
            console.group('destroyed Destruction completion status===============>');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);  
            console.log("%c%s", "color:red","data   : " + this.$data); 
            console.log("%c%s", "color:red","message: " + this.message)
        }
    })
</script>
</body>
</html>

Additional description

1. When did the hook trigger?

Vue document source code: when instantiating

function Vue(opt){    

    this._init(opt)

}
Vue.prototype._init(opt){
    ... Merge option
    ... Set initial value, event and other data
    initLifecycle(vm)
    callHook(vm, 'beforeCreate');
    ... Initialization options and other data
    callHook(vm, 'created');
    ...Get attached DOM Parent node
    callHook(vm, 'beforeMount');
    ...Parse the template into a rendering function, execute the rendering function, and generate DOM Insert page
    vm._isMounted = true;
    callHook(vm, 'mounted');
}
// This function is called when the component is updated
Vue.prototype._update = function(

    vnode, hydrating

) {    

    if (vm._isMounted) {

        callHook(vm, 'beforeUpdate');
    }
    ...Call the rendering function again, compare the old node with the new node, get the minimum difference, and then update only this part of the page
    callHook(vm, 'updated');
}
// This function is called when the node is removed
Vue.prototype.$destroy = function() {
    callHook(vm, 'beforeDestroy');
    vm._isBeingDestroyed = true;
    ...Instance is eliminated, remove all watcher
    vm._isDestroyed = true;
    ...DOM Removed
    callHook(vm, 'destroyed');
}

When executing the hook, this function will be triggered to traverse the execution and bind the context

function callHook(vm, hook) {    

    // It's from me created Equal callback

    var handlers = vm.$options[hook];    

    if (handlers) {        

    for (var i = 0,j = handlers.length; i < j; i++) {

            handlers[i].call(vm);
        }
    }
}

summary

1. Through a simple understanding of the eight stages of Vue life cycle, it can be applied in later development. Different operations are taken for hooks in different stages to better realize our business code and handle more complex business logic.

2. References Vue official website

3. Create project application next

Topics: Javascript Vue Attribute