深入瞭解vue生命週期
生命週期:Vue 實例從開始創建、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是 Vue 的生命週期,各個階段有相對應的事件鉤子
一,生命週期鉤子函數
生命週期鉤子 | 組件狀態 | 最佳實踐 |
---|---|---|
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 實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷燬 | - |
注意:
- created階段的ajax請求與mounted請求的區別:前者頁面視圖未出現,如果請求信息過多,頁面會長時間處於白屏狀態;
mounted
不會承諾所有的子組件也都一起被掛載。如果你希望等到整個視圖都渲染完畢,可以用 vm.$nextTick;- 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
瀏覽器裏打開,F12
看console
就能發現
beforecreated
:el
和data
並未初始化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();
完