深入瞭解Vue生命週期 - Vue2.0

深入瞭解vue生命週期

生命週期:Vue 實例從開始創建、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是 Vue 的生命週期,各個階段有相對應的事件鉤子


一,生命週期鉤子函數

clipboard.png

 

生命週期鉤子 組件狀態 最佳實踐
beforeCreate 實例初始化之後,this指向創建的實例,不能訪問到data、computed、watch、methods上的方法和數據

常用於初始化非響應式變量

created 實例創建完成,可訪問data、computed、watch、methods上的方法和數據,未掛載到DOM,不能訪問到$el屬性,$ref屬性內容爲空數組 常用於簡單的ajax請求,頁面的初始化
beforeMount 在掛載開始之前被調用,beforeMount之前,會找到對應的template,並編譯成render函數 -
mounted 實例掛載到DOM上,此時可以通過DOM API獲取到DOM節點,$ref屬性可以訪問 常用於獲取VNode信息和操作,ajax請求
beforeupdate 響應式數據更新時調用,發生在虛擬DOM打補丁之前 適合在更新之前訪問現有的DOM,比如手動移除已添加的事件監聽器
updated 虛擬 DOM 重新渲染和打補丁之後調用,組件DOM已經更新,可執行依賴於DOM的操作 避免在這個鉤子函數中操作數據,可能陷入死循環
beforeDestroy 實例銷燬之前調用。這一步,實例仍然完全可用,this仍能獲取到實例 常用於銷燬定時器、解綁全局事件、銷燬插件對象等操作
destroyed 實例銷燬後調用,調用後,Vue 實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷燬 -

注意:

  1. created階段的ajax請求與mounted請求的區別:前者頁面視圖未出現,如果請求信息過多,頁面會長時間處於白屏狀態;
  2. mounted 不會承諾所有的子組件也都一起被掛載。如果你希望等到整個視圖都渲染完畢,可以用 vm.$nextTick
  3. vue2.0之後主動調用$destroy()不會移除dom節點,作者不推薦直接destroy這種做法,如果實在需要這樣用可以在這個生命週期鉤子中手動移除dom節點。

 

二,生命週期探究


對於執行順序和什麼時候執行,看上面兩個圖基本有個瞭解了。下面我們將結合代碼去看看鉤子函數的執行。

<!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 : "xuxiao is boy" 
          },
           beforeCreate: function () {
                    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: function () {
                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: function () {
                console.group('beforeMount 掛載前狀態===============》');
                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); //已被初始化  
            },
            mounted: function () {
                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: function () {
                console.group('beforeUpdate 更新前狀態===============》');
                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 更新完成狀態===============》');
                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 銷燬前狀態===============》');
                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 銷燬完成狀態===============》');
                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>

三,create 和 mounted 相關

咱們在chrome瀏覽器裏打開,F12console就能發現

beforecreatedeldata 並未初始化 
created:完成了 data數據的初始化,el沒有 
beforeMount:完成了 el 和 data 初始化 
mounted :完成掛載

另外在標紅處,我們能發現el還是{{message}},這裏就是應用的 Virtual DOM(虛擬Dom)技術,先把坑佔住了。到後面mounted掛載的時候再把值渲染進去。

這裏寫圖片描述

update 相關

這裏我們在 chrome console裏執行以下命令

app.message= 'yes !! I do';

下面就能看到data裏的值被修改後,將會觸發update的操作。

這裏寫圖片描述

destroy 相關

有關於銷燬,暫時還不是很清楚。我們在console裏執行下命令對 vue實例進行銷燬。銷燬完成後,我們再重新改變message的值,vue不再對此動作進行響應了。但是原先生成的dom元素還存在,可以這麼理解,執行了destroy操作,後續就不再受vue控制了。

app.$destroy();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章