zoukankan      html  css  js  c++  java
  • 【Vue笔记】-- 详解vue生命周期

      针对于Vue的生命周期进行详细的说明,方面加深对各个方法的引用。

    引言:

      前几天重新回顾vue官网时,看到vue的生命周期,想着自己用vue开发了快一年了,就总结总结vue知识,再次加深自己对vue的理解。

    正文:

           首先上初始化代码(代码不完整,完整代码在下面的github里),然后在控制台打印并查看结果(console.group()表示该范围内是一个组,方便查看一组)
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>vue生命周期</title>
      <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
    </head>
    <body>
      <div id="app">
        <h1>{{message}}</h1>
      </div>
    </body>
    <script>
      var vm = new Vue({
        el: '#app',
        data: {
          message: 'Vue'
        },
        beforeCreate: function() {
          console.group('------beforeCreate创建前状态------');
          console.log(this.$el); 
          console.log(this.$data); 
          console.log(this.message) 
        },
        created: function() {
          console.group('------created创建完毕状态------');
          console.log(this.$el); 
          console.log(this.$data);
          console.log(this.message); 
        },
        beforeMount: function() {
          console.group('------beforeMount挂载前状态------');
          console.log(this.$el);
          console.log(this.$data); 
          console.log(this.message);  
        },
        mounted: function() {
          console.group('------mounted 挂载结束状态------');
          console.log(this.$el);    
          console.log(this.$data); 
          console.log(this.message); 
        },
        beforeUpdate: function () {
          console.group('beforeUpdate 更新前状态===============》');
          console.log(this.$el);  
          console.log(this.$data); 
          console.log(this.message); 
        },
        updated: function () {
          console.group('updated 更新完成状态===============》');
          console.log(this.$el);
          console.log(this.$data); 
          console.log(this.message); 
        },
        beforeDestroy: function () {
          console.group('beforeDestroy 销毁前状态===============》');
          console.log(this.$el);    
          console.log(this.$data); 
          console.log(this.message); 
        },
        destroyed: function () {
          console.group('destroyed 销毁完成状态===============》');
          console.log(this.$el);  
          console.log(this.$data); 
          console.log(this.message)
        }
      })
      
    </script>
    </html>
    View Code

      结果显示如下: 

      

      ps:因为没有更新数据和销毁数据,所以beforeUpdate,updated,beforeDestroy和destroyed等钩子函数没有触发,只打印出beforeCreate,created,beforeMount和mounted的钩子函数情况。

      在vue生命周期图例中可知,可以分为以下几个步骤:

      一 beforeCreate—created间的生命周期 

     
                               
     
      这一步从图中可知:是初始化data和事件,注册和反映(这个翻译感觉不太对劲,说白了就是初始化)。
      打印结果如下:
      
      通过代码结果可知:$el,$data以及message都为undefined,说明是处于初始化状态。 
     

      二 created—beforeMount间的生命周期

               
      
        这一步,会进行两次判断:
        * 判断对象是否有el选项。
          如果有的话就继续向下编译,
          如果没有el选项,则停止编译。也就意味着停止了生命周期,直到在该vue实例上再次调用vm.$mount(el)才会继续往下编译。
          代码结果演示如下:
          1 当$el不挂载到vue时(注释掉new Vue()里的el)
          结果如下:
     
          
     
          通过以下代码可知:当$el不挂载到vue时,只会进行beforeCreated和created这两个钩子函数,不会进行beforeMounted和mounted钩子函数。
          
          2 当重新调用时(输入vm.$mount(el))
     
          
            
          通过打印结果可知:在输入vm.$mount('#app')时,发现这四个钩子函数都实行了。可以推断,mount这一环节是保证$el已经挂载,且可以进行任何数据操作。
          
        ** 判断el是否有template模板:
          如果有的话直接通过渲染函数渲染出来。
          如果没有的话,就直接调用$el的外部html进行渲染。
         ps:所谓的template的就是vm对象里的template属性的值,如果template没有值,则会调用外部的html。
        以下demo实现,结论和打印结果:
          1 当有template时:
    var vm = new Vue({
        el: '#app',
        template:'<h1 style="color:red">{{message}}</h1>',
        data: {
          message: 'Vue'
        }
      })

        

       

        2 当无template时:

    <body>
      <div id="app">
        <h1>{{message}}</h1>
      </div>
    </body>

        

        3 当两者存在时,会优先选择template渲染函数。

    <body>
      <div id="app">
        <h1>{{message}}</h1>
      </div>
    </body>
    <script>
      var vm = new Vue({
        el: '#app',
        template:'<h1 style="color:red">{{message}}</h1>',
        data: {
          message: 'Vue'
        }
      })
    </script>

        

        4 两者不存在时,则不渲染也不报错

        ps:另外,Vue对象中也有render函数,和template一样,render可以返回一个createElement参数,进行渲染。
    <body>
      <div id="app">
        <h1>{{message}}</h1>
      </div>
    </body>
    <script>
      var vm = new Vue({
        el: '#app',
        template:'<h1 style="color:red">{{message}}</h1>',
        render: function (createElement, context) {
            return createElement('h1',`${this.message}1111`)
        },
        data: {
          message: 'Vue'
        },
      })
    </script>

        

        通过演示可知:发现render比template优先级高一些。
               所以三个渲染的优先级是:render函数选项  > template参数  > 外部HTML

         

      三 beforeMount—mounted钩子函数的生命周期

              

        
        这一步的生命周期在于虚拟dom树的渲染。
        
        

         通过打印结果可知:

          在beforeMounted钩子函数中,挂载了$el,但只拿到{{message}},没有完成渲染,
          而mounted钩子函数是已经完成了整个流程。
          所以Vue生命周期图例的意思应该是:给vue实例挂载$el,并且挂载到虚拟dom元素上。(一开始没明白这一步,现在才恍然大悟)。

      四 beforeUpdate—updated间的生命周期

              

          这一步是当vue的data数据发生改变,就会触发对应组件的重新渲染。然后依次触发beforeUpdate和update钩子函数。

        ps:看到有位博主说到一个重点!这俩个钩子函数只能在已渲染到模板里的数据发生改变后才能触发,否则不触发。例子如下:
    <body>
      <div id="app">
        <!-- <h1>{{message}}</h1> -->
      </div>
    </body>
    <script>
      var vm = new Vue({
        el: '#app',
        // template:'<h1 style="color:red">{{message}}</h1>',
        data: {
          message: 'Vue'
        },
        beforeUpdate: function () {
          console.group('beforeUpdate 更新前状态===============》');
          console.log(this.$el);  
          console.log(this.$data); 
          console.log(this.message); 
        },
        updated: function () {
          console.group('updated 更新完成状态===============》');
          console.log(this.$el);
          console.log(this.$data); 
          console.log(this.message); 
        },
      })
      vm.message = 'aaaa';
    </script>

      结果可知:没有触发钩子函数。

      

      当把template的注释去掉,结果如下:触发了更新前后的钩子函数。

      

       五 beforeDestroy—destroyed间的生命周期

            

        beforeDestroy钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。
        destroyed钩子函数在Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
        实例如下:<script>
      var vm = new Vue({
        el: '#app',
        template:'<h1 style="color:red">{{message}}</h1>',
        data: {
          message: 'Vue'
        },
        beforeDestroy: function () {
          console.group('beforeDestroy 销毁前状态===============》');
          console.log(this.$el);    
          console.log(this.$data); 
          console.log(this.message); 
        },
        destroyed: function () {
          console.group('destroyed 销毁完成状态===============》');
          console.log(this.$el);  
          console.log(this.$data); 
          console.log(this.message)
        }
      })
      vm.$destroy();
      vm.message='11111'
    </script>

       

      ps:因为只有$destroy()方法,所以没法判断beforeDestroy和destroyed的区别

      结果如下:发现销毁之后,再重新给message赋值,没效果。可见destroyed钩子函数在$destroy()方法实行后会销毁和当前实例有关的东西,不会再次对该实例进行操作

    结尾:

         

      以上都是自己对vue的生命周期的理解,从一开始懵懂,到依次开发vue项目,回头再看这生命周期,就有一种“原来如此”的感觉,感到vue强大之处。

      我是17号小白,我把完整代码放到gitHub里了,有需要实践的请前往clone。地址:https://github.com/sqh17/notes/blob/master/ways/vueLifecycle.html。

      以上若有不对的地方,请大家能及时私信我或者下方评论,我们一起加油进步。

     参考文献:

  • 相关阅读:
    61. 最长不含重复字符的子字符串
    60. 礼物的最大价值 (未理解)
    59. 把数字翻译成字符串
    58. 把数组排成最小的数
    57. 数字序列中某一位的数字 (不懂)
    spring data jpa 官方文档
    idea 编译报错 源发行版 1.8 需要目标发行版 1.8
    idea maven 依赖报错 invalid classes root
    solr
    spring boot 官方文档
  • 原文地址:https://www.cnblogs.com/sqh17/p/9325457.html
Copyright © 2011-2022 走看看