理解vue實例的生命周期和鈎子函數


. vue實例的生命周期

通俗來說 vue的生命周期就是vue實例從創建到銷毀的過程,我將這個過程中的一些關鍵點抽取出來,簡化為下面這個流程圖:


 
生命周期

2. 結合生命周期理解鈎子函數

vue2.0提供了一系列鈎子函數,這些函數和生命周期的各個階段一一對應:


 
生命周期和鈎子函數
鈎子函數 描述
beforeCreate 在實例初始化之后,數據觀測(data observer)
和 event/watch事件配置之前被調用
created 在實例創建完成后立即被調用,在這一步實例已經完成了:
數據觀測、屬性和方法的運算和 event/watch事件的回調,
但是$el屬性目前不可見。
beforeMount 在掛載開始之前被調用
mounted 在掛載成功后被調用,el被新創建的vm.$el替換
beforeUpdate 數據更新之前調用
update 數據更新完成時調用,組件dom已經更新
activated 組件被激活時調用
deactivated 組件被移除時調用
beforeDestory 組件銷毀前調用
destoryed 組件銷毀后調用

3. 結合代碼理解鈎子函數

為了更深入的理解各個鈎子函數的區別,我們結合代碼去看看:

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>
<script type="text/javascript">
  export default {
    data(){
      return{
        message : "鈎子函數小測試"
      }
    },
    beforeCreate(){
      console.group('beforeCreate 創建前狀態 ------------>');
      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)
    },
    created() {
      console.group('created 創建完畢狀態 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el); //undefined
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化
    },
    beforeMount() {
      console.group('beforeMount 掛載前狀態 ------------>');
      console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化
    },
    mounted() {
      console.group('mounted 掛載結束狀態 ------------>');
      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); //已被初始化
    },
    beforeUpdate() {
      console.group('beforeUpdate 更新前狀態 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);
      console.log('真實dom結構:' + document.getElementById('app').innerHTML);
      console.log("%c%s", "color:red","data   : " + this.$data);
      console.log("%c%s", "color:red","message: " + this.message);
    },
    updated() {
      console.group('updated 更新完成狀態 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);
      console.log('真實dom結構:' + document.getElementById('app').innerHTML);
      console.log("%c%s", "color:red","data   : " + this.$data);
      console.log("%c%s", "color:red","message: " + this.message);
    },
    beforeDestroy() {
      console.group('beforeDestroy 銷毀前狀態 ------------>');
      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() {
      console.group('destroyed 銷毀完成狀態 ------------>');
      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>
(1)創建階段

創建的標志點是New vue(),beforeCreate和created都發生在創建動作之后,但區別在於
beforeCreate觸發的時候數據還沒初始化和綁定,而created的時候就生成好了,具體我們看看console的內容:

 
創建階段

數據很明顯了,beforeCreate觸發的時el、data都沒初始化,但到created的時候雖然el依然沒有初始化,但是data已經生成了,並且成功將message的值綁定上。

(2)掛載階段

beforeMount和mounted兩者主要區別在於模板是否編譯和掛載了。


 
掛載階段

el是用來告訴實例在那個元素上進行掛載的,我們可以看到beforeMount觸發的時候el還是沒有初始化,而到mounted的時候已經找到要掛載的元素,並且將模板編譯了。

(3)更新階段

加載頁面的時候,其實到mounted這里就結束了,更新和銷毀並不會觸發到。
這里我另外寫了一個方法去改變message的值,觸發更新:

 methods:{ change(){ this.message = '不如更新一下咯' } }, 

控制台的結果:


 
更新階段

我們可以看到,當我們去改變message的值的時候,觸發了beforeUpdate函數,這個時候$el的值已經更改了,但是dom並沒有變動。到update的時候,才真正去更新dom結構。

(4)銷毀階段

再寫一個方法來觸發銷毀:

 methods:{
      destroy(){
        this.$destroy()
      }
    },

 

控制台的結果:


 
image.png

可以發現beforeDestory和destoryed打印出來的結果並沒有什么特別,el的值data的數據依然在的。這是因為$destroy只是銷毀一個實例,清理它與其它實例的連接,解綁它的全部指令及事件監聽器,並不會清除data的數據或者清除dom。具體理解可參考:https://cn.vuejs.org/v2/api/#vm-destroy

文章來源:https://www.jianshu.com/p/98517bd49179

 


免責聲明!

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



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