寫在前面: 我是「揚帆向海」,這個暱稱來源於我的名字以及女朋友的名字。我熱愛技術、熱愛開源、熱愛編程。
技術是開源的、知識是共享的
。
這博客是對自己學習的一點點總結及記錄,如果您對 Java、算法 感興趣,可以關注我的動態,我們一起學習。
用知識改變命運,讓我們的家人過上更好的生活
。
一、vue的生命週期
正如人類有生命週期一樣,一個程序本身和程序中的每一個實例和組件都存在生命週期。
一個人的生命週期都是由出生開始,到死亡結束,從出生到死亡的幾十年時間裏,會發生很多的大事件,這些事件將會影響一些人或整個世界。
對於一個程序或Vue.js中的一個實例來說,其生命週期開始於創建,當新建一個實例的時候,生命週期就開始了;而當銷燬一個實例之後,生命週期就結束了。
每個 Vue 實例在被創建時都要經過一系列的初始化過程——例如,需要設置數據監聽、編譯模板、將實例掛載到 DOM 並在數據變化時更新 DOM 等。同時在這個過程中也會運行一些叫做生命週期鉤子的函數,這給了用戶在不同階段添加自己的代碼的機會。
二、鉤子函數
Vue實例從創建到銷燬的過程中 ,這些過程中會伴隨着一些函數的自調用。將這些函數稱爲
鉤子函數
。
爲什麼叫做鉤子呢?原因是對於某個實例事件發生後需要響應已經預設好的代碼,即某一個鉤子鉤住了一個實例的狀態或者事件。
1. 創建階段的生命週期
① beforeCreate
在實例初始化之後,數據觀測 (data observer) 和 event/watcher 事件配置之前被調用。
此時的 data 和 methods 中的 數據都還沒有沒初始化
。
② created
在實例創建完成後被立即調用。在這一步,實例已完成以下的配置:數據觀測 (data observer),屬性和方法的運算,watch/event 事件回調。也就是
此時 data 和 methods已經可以初始化完成了
。然而,掛載階段還沒開始,$el 屬性目前尚不可用。 頁面還沒有渲染出來。
注意:
如果要調用 methods 中的方法,或者操作 data 中的數據,最早只能在 created 中進行操作。
③ beforeMount
在掛載開始之前被調用。此時
頁面上還看不到真實的數據
,因爲模板在內存中編譯完成了,但是還沒有把模板渲染到頁面中。
注意:
在 beforeMount 執行的時候,頁面中的元素還沒有被真正替換過來,顯示的是之前寫的一些模板字符串。
④ mounted
實例被掛載後調用,這時 el 被新創建的 vm.$el 替換了。此時數
據已經真實渲染到頁面上了
。
mounted 是實例創建期間的最後一個生命週期函數,當執行完 mounted 就表示,實例已經被完全創建好了。
注意:
mounted 不會保證所有的子組件也都一起被掛載。如果你希望等到整個視圖都渲染完畢,可以在 mounted 內部使用 vm.$nextTick:
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
2. 運行階段的生命週期
① beforeUpdate
數據更新時調用,發生在虛擬 DOM 打補丁之前。此時
頁面上數據還是舊的,但是 data 數據是最新的
,頁面還沒有和最新的數據保持同步。
這裏適合在更新之前訪問現有的 DOM,比如手動移除已添加的事件監聽器。
② updated
由於數據更改導致的虛擬 DOM 重新渲染和打補丁,在這之後會調用該鉤子。此時
頁面上數據已經替換成最新的
。
當這個鉤子被調用時,組件 DOM 已經更新,所以你現在可以執行依賴於 DOM
的操作。然而在大多數情況下,你應該避免在此期間更改狀態。如果要相應狀態改變,通常最好使用計算屬性或 watcher 取而代之。
3. 銷燬階段的生命週期
① beforeDestroy
實例銷燬之前調用。在這一步,實例仍然完全可用。
② destroyed
實例銷燬後調用。該鉤子被調用後,對應 Vue 實例的所有指令都被解綁,所有的事件監聽器被移除,所有的子實例也都被銷燬。
三、代碼示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>生命週期鉤子函數</title>
<script type="text/javascript" src="js/vue.js"></script>
<style>
.btn-update {
text-align: center;
color:white;
background-color: green;
font-size: 15px;
margin-top: 10px;
}
.btn-destroy {
text-align: center;
color: white;
background-color: red;
font-size: 15px
}
.btn-wrap {
margin: 10px auto;
width: 32%;
}
.str {
background-color: skyblue;
color: white;
font-size: 30px;
width: 18%;
}
</style>
</head>
<body>
<div id="app">
<div class='str'>{{msg}}</div>
<button class='btn-update' @click='update'>更新</button>
<button class='btn-destroy' @click='destroy'>銷燬</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: '我是揚帆向海'
},
methods: {
update: function () {
this.msg = '我被改變了~~~';
},
destroy: function () {
this.$destroy();
}
},
beforeCreate: function () {
console.log('beforeCreate---創建前狀態');
},
created: function () {
console.log('created---創建完畢狀態');
},
beforeMount: function () {
console.log('beforeMount---掛載前狀態');
},
mounted: function () {
console.log('mounted---掛載結束狀態');
},
beforeUpdate: function () {
console.log('beforeUpdate---數據更新之前狀態');
},
updated: function () {
console.log('updated---數據更新完成狀態');
},
beforeDestroy: function () {
console.log('beforeDestroy---實例銷燬之前狀態');
},
destroyed: function () {
console.log('destroyed---實例銷燬完成狀態');
}
});
</script>
</body>
</html>
在頁面加載的過程中,會依次執行創建階段的四個鉤子函數:
第一次頁面加載會觸發 beforeCreate, created, beforeMount, mounted 這幾個鉤子函數。DOM 渲染在 mounted 中就已經完成了。
生命週期鉤子函數加載過程的效果圖
由於水平有限,本博客難免有不足,懇請各位大佬不吝賜教!