. 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() } },
控制台的結果:

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