今天小編給大家詳細講解一下 vue 的生命周期。希望大家多多指教,哪里有遺漏的地方,也請大家指點出來 謝謝。
一、 怎么理解 Vue 的生命周期的?
生命周期:從無到有,到到無的一個過程。Vue的生命周期對組件來說的 或 實例來說。
簡單理解:比如我們都知道 js 中的定時器,定時器都有開始的那一秒,已經執行過程中,最后執行完畢,我們的 Vue 的生命周期就好像 定時器一樣,有許多過程,他們就像鈎子一樣,相互牽連着。
1. 在Vue當中 組件(自定義的一些標簽) 瀏覽器是無法解析的。
2. 那組件的自定義標簽怎么使用的呢?
主要分一下幾個過程:
從創建它 》到使用它》到使用完畢》在銷毀它
3. vue實例對象是最大的組件(也可以稱它為根組件)
什么是鈎子函數?
因為 Vue 的生命周期都是分 一個階段一個階段的 並且都是相連的。
二、Vue的生命周期 主要分 四個階段 和 八個過程
我們先說 哪四個階段:
Create 創建
Mount 掛載(加載)
Update 更新
Destroy 銷毀
又是哪八個過程呢:
Create之前和Create之后
Mount之前和Mount之后
Update之前和Update之后
Destroy之前和Destroy之后
debugger 斷點調試 在工作當中會經常用得到的
Vue的生命周期都寫在 Vue實例下
1. 第一個過程 beforeCreate
beforeCreate 實例初始化之前。數據沒有加載(data),頁面更沒顯示。
第一步初始化之前數據(data)還沒有拿到呢,data還沒有存在就會執行它。
// 這是個函數,初始化之前
beforeCreate(){
console.log(this.a) // 會打印 undefined 為什么是undefined?說明我在執行這個函數,沒數據
debugger
}
數據還沒有加載過來,往往在這個階段做 loading 請求數據 請求狀態,因為什么都沒有

2. 第二個過程 created
1. Created 實例初始化之后。它僅僅只請求到了數據,事件,屬性等。但是沒有加載,頁面依然沒有顯示。
在這個階段 往往發送數據(ajax)請求,http請求
created(){
console.log(this.a)//能請求到數據,但頁面不顯示
debugger
}

2. 在created之后這個 $el 屬性還是不可見的,它會在created和beforeMount判斷一下有沒有$el這個選項。
3. Create到beforeMount 有個判斷:
1. Create到beforeMount主要是找模板,模板都是虛擬的
2. Create -之間的過程> beforeMount之間 vue會在options 中查找有沒有 el 選項,有就把他作為模板,沒有通過 vm.$mount() 這個方法去掛載。
說白了你指定模板可以通過 el:”#app”指定,也可以通過vm.$mount()去指定
}).$mount("#app") el:"#app",
3. 有el就繼續判斷,你有沒有template屬性,如果還要模板選項(屬性),那就直接把模板渲染出去,沒有就把el的東西渲染出去扔掉#app body里面。
4. 如果有模板就渲染模板的東西可以看的完全沒有el了
5. Created之后數據請求過來了,就是找對應的模板


3. 第三個過程 beforeMount
beforeMount vue會將 el對應的模板加到 vm.$el 中去,但是還沒有掛載出去,頁面還沒有顯示。

現在有個問題?視圖沒渲染為啥頁面會有{{a}},button?
首先視圖沒有出來不是說頁面沒有出來,瀏覽器在加載頁面是從上到下,從上到下加載過程中,是先執行body,還是script?先執行body,body該解析的解析,像html標簽能識別(有解析標簽的功能),而{{a}},它給當作內容渲染了,load不識別,不識別就不管了,然后你在創建實例的時候,又把里面的東西當作模板重新再次渲染。
什么是視圖:
是模板里面的東西,現在還沒有加載就不是模板。什么時候是模板?created或beforeMount

在beforeMount的時候我們可以找到模板了,只是還沒有加載
beforeMount(){
console.log(this.$el)
debugger;
},

4. 第四個過程 mounted
mounted 頁面加載出來了,所有的節點都出來了
mounted(){
console.log(this.$el)
debugger;
},

5. 第五個過程 beforeUpdated 更新也分兩個 更新前 和 更新后
beforeUpdated 數據更新前
beforeUpdate(){
console.log("數據准備更新")
debugger;
},


在虛擬 dom 中使用 differ算法,在內存中實現,Mounted之前過程就不管了,更新就加載,加載過程中不是全部都加載,如果是全部加載又要回到出發點,哪里更新了我在虛擬dom進行對比下,對比完重新在去掛載,誰變了誰去掛載,誰去更新,之前的整個dom樹不會跟着你一起更新,如果跟着你更新又會回到起點(beforeCreate),muntud之前都不管了。如果想看屬性的變化可以使用 watch(屬性監聽)這個方法。
6. 第六個過程 Updated
Updated 更新完
更新完,在渲染,誰改變了渲染誰。不是整個dom樹重新渲染

7. 第七個過程 銷毀也分兩個,銷毀前和銷毀后
銷毀前 before Destory
銷毀后 destroy
實例銷毀需要人為觸發
注意:這個地方問題很多尤其是組件拼接,組件里面套組件的時候
銷毀:之前渲染好的保持不變 保留下來,后面再使用這個實例就不起作用了。
怎么銷毀?
通過 vm.$destory()
三、組件的生命周期:
實例里面套組件
組件也有生命周期
嵌套組件生命周期的執行順序:
先執行實例的vm.beforecreate -> 依然是vm.created -> 下一個還是vm.beforeMount ->這一塊主要找el模板 模板里有組件,有組件開始走子組件里面的了是son.beforecreate。后期調數據的時候哪里該調哪里不該調,跟順序有很大關系,如果調錯了數據不會被更改的。

先執行實例的vm.beforecreate -> vm.created ->vm.beforeMount -> son.beforecreate -> son.created ->son.beforeMount ->繼續執行 son.mountnd -> vm.mounted(又回到父級身上)
注意:正常加載是這樣的:
先執行實例的vm.beforecreate -> vm.created ->vm.beforeMount ->先執行到父組件的beforeMount准備加載,再去找模板,發現模板里面有子組件然后對子組件進行渲染。son.beforecreate -> son.created ->son.beforeMount ->繼續執行 son.mountnd ->,加載完之后再去加載父組件。
以上三個順序是一樣的,我給細節化,方便大家理解
注意:
1. 組件嵌套的時候數據怎么改都改不了,說明根生命周期順序有關。
2. 請求的數據在子組件是a,但是在父組件還是原來的,所以給生命周期順序有關。
更改組件類的數據 修改子組件的數據順序:
先執行實例的vm.beforecreate -> vm.created ->vm.beforeMount -> son.beforecreate -> son.created ->son.beforeMount ->繼續執行 son.mountnd -> vm.mounted(又回到父級身上) -> son.beforeUpdate -> son.updated
組件更新數據,只會調用自己的 beforeupdate和updated ,不會影響到其它組件的更新鈎子。如果說父組件獲取子組件中的標簽中的內容(這個內容會被子組件修改),父組件獲取的都是修改前的內容,因為子組件的更新,不會再去觸發父組件的 mounted,this. $nexTick() 它是組件中(包括子組件)所有的鈎子執行完畢之后才會觸發。
作者:晉飛翔
手機號(微信同步):17812718961
希望本篇文章 能給正在學習 前端的朋友 或 以及工作的朋友 帶來收獲 不喜勿噴 如有建議 多多提議 謝謝!!!
