【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。

  以上若有不對的地方,請大家能及時私信我或者下方評論,我們一起加油進步。

 

 

 

 

 參考文獻:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM