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。

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

     参考文献:

  • 相关阅读:
    诸葛亮会议
    软件工程第十次作业——例行报告
    Beta阶段中间产物
    Beta冲刺贡献分数分配结果
    “Hello World!”团队第六周的第六次会议
    “Hello World!”团队第六周的第五次会议
    Beta发布文案+美工
    “Hello World!团队”Beta发布—视频链接+文案+美工
    软件工程第九次作业——例行报告
    “Hello World!”团队第五周第五次会议
  • 原文地址:https://www.cnblogs.com/sqh17/p/9325457.html
Copyright © 2011-2022 走看看