Vue生命周期深入分析總結(jié)
一、生命周期圖
官網(wǎng)圖片,先了解一下流程

二、生命周期三個(gè)組成部分
第一節(jié)-初始化
beforeCreate
初始化之后,數(shù)據(jù)觀測(data observer) 和 event/watcher 事件配置之前被調(diào)用。
vue實(shí)例中的el,data,data中的message都為undefined。
created
實(shí)例已經(jīng)創(chuàng)建完成之后被調(diào)用。在這一步,實(shí)例已完成以下的配置:數(shù)據(jù)觀測(data observer),屬性和方法的運(yùn)算, watch/event 事件回調(diào)。然而,掛載階段還沒開始,$el 屬性目前不可見。
主要應(yīng)用:調(diào)用數(shù)據(jù),調(diào)用方法,調(diào)用異步函數(shù)
beforeMount
載入前(完成了data和el數(shù)據(jù)初始化),可是頁面中的內(nèi)容仍是vue中的占位符,data中的message信息沒有被掛在到Bom節(jié)點(diǎn)中,在這里能夠在渲染前最后一次更改數(shù)據(jù)的機(jī)會(huì),不會(huì)觸發(fā)其余的鉤子函數(shù),通常能夠在這里作初始數(shù)據(jù)。這個(gè)階段操作DOM是不奏效的。
mounted
載入后html已經(jīng)渲染(ajax請(qǐng)求能夠放在這個(gè)函數(shù)中),把vue實(shí)例中的data里的message掛載到BOM節(jié)點(diǎn)中去。
第二節(jié)-更新狀態(tài)
beforeUpdate
狀態(tài)完成更新之前(data中數(shù)據(jù)已發(fā)生變化,view層數(shù)據(jù)變化之前),后vue的虛擬dom機(jī)制會(huì)從新構(gòu)建虛擬dom與上一次的虛擬dom樹利用diff算法進(jìn)行對(duì)比以后從新渲染。
updated
數(shù)據(jù)已經(jīng)更改完成,dom也從新render完成。
第三節(jié)-銷毀實(shí)例
Vm.$destroy():銷毀后自定義事件會(huì)失效,但原生DOM事件依然有效。銷毀后會(huì)調(diào)用下面兩個(gè)鉤子。
beforeDestroy
銷毀前執(zhí)行($destroy方法被調(diào)用的時(shí)候就會(huì)執(zhí)行),通常在這里善后:清除計(jì)時(shí)器、清除非指令綁定的事件等等…’)。
destroyed
銷毀后 (Dom元素存在,只是再也不受vue控制),卸載watcher,事件監(jiān)聽,子組件
簡單的對(duì)生命周期總結(jié)
常用的生命周期鉤子
1.mounted: 發(fā)送ajax請(qǐng)求、啟動(dòng)定時(shí)器、綁定自定義事件、訂閱消息等【初始化操作】。
2.beforeDestroy: 清除定時(shí)器、解綁自定義事件、取消訂閱消息等【收尾工作】。
關(guān)于銷毀Vue實(shí)例
1.銷毀后借助Vue開發(fā)者工具看不到任何信息。
2.銷毀后自定義事件會(huì)失效,但原生DOM事件依然有效。
3.一般不會(huì)在beforeDestroy操作數(shù)據(jù),因?yàn)榧幢悴僮鲾?shù)據(jù),也不會(huì)再觸發(fā)更新流程了。
三、代碼測試生命周期
后面附有解釋
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue實(shí)例的生命周期</title>
</head>
<body>
<div id="app">
<h1>測試生命周期</h1>
<div>{{msg}}</div>
<hr>
<h3>測試beforeUpdate和update兩個(gè)鉤子函數(shù)</h3>
<button @click="handlerUpdate">更新數(shù)據(jù)</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
msg: "12345"
},
methods: {
handlerUpdate() {
this.msg=this.msg.split("").reverse().join("")
}
},
//按照示意圖依次調(diào)用
beforeCreate(){
console.log("調(diào)用了beforeCreate鉤子函數(shù)");
},
created(){
console.log("調(diào)用了created鉤子函數(shù)");
},
beforeMount(){
console.log('調(diào)用了beforeMount鉤子函數(shù)');
},
mounted(){
console.log('調(diào)用了mounted鉤子函數(shù)');
},
beforeUpdate(){
console.log("調(diào)用了beforeUpdate鉤子函數(shù)")
},
updated(){
console.log("調(diào)用了updated鉤子函數(shù)");
},
beforeDestroy(){
console.log("調(diào)用了beforeDestroy鉤子函數(shù)");
},
destroyed(){
console.log("調(diào)用了destroyed鉤子函數(shù)");
}
})
</script>
</body>
</html>
初始化頁面依次調(diào)用了:
- 調(diào)用了beforeCreate鉤子函數(shù)
- 調(diào)用了created鉤子函數(shù)
- 調(diào)用了beforeMount鉤子函數(shù)
- 調(diào)用了mounted鉤子函數(shù)
點(diǎn)擊更新數(shù)據(jù)后:
12345變成了54321,此時(shí)調(diào)用了:
- 調(diào)用了beforeUpdate鉤子函數(shù)
- 調(diào)用了updated鉤子函數(shù)
打開F12控制臺(tái) 直接輸入app.$destroy()主動(dòng)銷毀Vue實(shí)例調(diào)用:
- 調(diào)用了beforeDestroy鉤子函數(shù)
- 調(diào)用了destroyed鉤子函數(shù)
四、再探究
beforeCreate之前
初始化鉤子函數(shù)和生命周期
beforeCreate和created鉤子函數(shù)間的生命周期
在beforeCreate和created之間,進(jìn)行數(shù)據(jù)觀測(data observer) ,也就是在這個(gè)時(shí)候開始監(jiān)控data中的數(shù)據(jù)變化了,同時(shí)初始化事件。
created鉤子函數(shù)和beforeMount間的生命周期
對(duì)于created鉤子函數(shù)和beforeMount有判斷:

el選項(xiàng)對(duì)生命周期影響
1.有el選項(xiàng)
new Vue({
el: '#app',
beforeCreate: function () {
console.log('調(diào)用了beforeCreat鉤子函數(shù)')
},
created: function () {
console.log('調(diào)用了created鉤子函數(shù)')
},
beforeMount: function () {
console.log('調(diào)用了beforeMount鉤子函數(shù)')
},
mounted: function () {
console.log('調(diào)用了mounted鉤子函數(shù)')
}
})
2.無el選項(xiàng)
new Vue({
beforeCreate: function () {
console.log('調(diào)用了beforeCreat鉤子函數(shù)')
},
created: function () {
console.log('調(diào)用了created鉤子函數(shù)')
},
beforeMount: function () {
console.log('調(diào)用了beforeMount鉤子函數(shù)')
},
mounted: function () {
console.log('調(diào)用了mounted鉤子函數(shù)')
}
})
證明沒有el選項(xiàng),則停止編譯,也意味著暫時(shí)停止了生命周期。生命周期到created鉤子函數(shù)就結(jié)束了。而當(dāng)我們不加el選項(xiàng),
但是手動(dòng)執(zhí)行vm.$mount(el)方法的話,也能夠使暫停的生命周期進(jìn)行下去,例如:
var app = new Vue({
beforeCreate: function () {
console.log('調(diào)用了beforeCreat鉤子函數(shù)')
},
created: function () {
console.log('調(diào)用了created鉤子函數(shù)')
},
beforeMount: function () {
console.log('調(diào)用了beforeMount鉤子函數(shù)')
},
mounted: function () {
console.log('調(diào)用了mounted鉤子函數(shù)')
}
})
app.$mount('#app')
template

同時(shí)使用template和HTML,查看優(yōu)先級(jí):
<h1>測試template和HTML的優(yōu)先級(jí)</h1>
<div id="app">
<p>HTML優(yōu)先</p>
</div>
<script>
var app = new Vue({
el:"#app",
data:{
msg:"template優(yōu)先"
},
template:"<p>{{msg}}</p>",
});
</script>結(jié)果:

結(jié)論
- 如果Vue實(shí)例對(duì)象中有template參數(shù)選項(xiàng),則將其作為模板編譯成render函數(shù)
- 如果沒有template參數(shù)選項(xiàng),則將外部的HTML作為模板編譯(template),也就是說,template參數(shù)選項(xiàng)的優(yōu)先級(jí)要比外部的HTML高
- 如果1,2條件都不具備,則報(bào)錯(cuò)
注意
Vue需要通過el去找對(duì)應(yīng)的template,Vue實(shí)例通過el的參數(shù),首先找自己有沒有template,如果沒有再去找外部的html,找到后將其編譯成render函數(shù)。
也可以直接調(diào)用render選項(xiàng),優(yōu)先級(jí):render函數(shù)選項(xiàng) > template參數(shù) > 外部HTML。
beforeMount和mounted鉤子函數(shù)間的生命周期

beforeMount
載入前(完成了data和el數(shù)據(jù)初始化),但是頁面中的內(nèi)容還是vue中的占位符,data中的message信息沒有被掛在到Dom節(jié)點(diǎn)中,在這里可以在渲染前最后一次更改數(shù)據(jù)的機(jī)會(huì),不會(huì)觸發(fā)其他的鉤子函數(shù),一般可以在這里做初始數(shù)據(jù)的獲取。
Mount
載入后html已經(jīng)渲染(ajax請(qǐng)求可以放在這個(gè)函數(shù)中),把vue實(shí)例中的data里的message掛載到DOM節(jié)點(diǎn)中去
這里兩個(gè)鉤子函數(shù)間是載入數(shù)據(jù)。
beforeUpdate鉤子函數(shù)和updated鉤子函數(shù)間的生命周期

在Vue中,修改數(shù)據(jù)會(huì)導(dǎo)致重新渲染,依次調(diào)用beforeUpdate鉤子函數(shù)和updated鉤子函數(shù)
如果待修改的數(shù)據(jù)沒有載入模板中,不會(huì)調(diào)用這里兩個(gè)鉤子函數(shù)
var app = new Vue({
el: '#app',
data: {
msg: 1
},
template: '<div id="app"><p></p></div>',
beforeUpdate: function () {
console.log('調(diào)用了beforeUpdate鉤子函數(shù)')
},
updated: function () {
console.log('調(diào)用了updated鉤子函數(shù)')
}
})
app.msg = 2
如果綁定了數(shù)據(jù),會(huì)調(diào)用兩個(gè)鉤子函數(shù):
<h1>測試有數(shù)據(jù)綁定修改數(shù)據(jù),鉤子函數(shù)調(diào)用情況</h1>
<div id="app">
</div>
<script>
var app = new Vue({
el:"#app",
template:"<p>{{msg}}</p>",
data:{
msg:"原數(shù)據(jù)"
},
beforeUpdate: function () {
console.log("調(diào)用了beforeUpdate鉤子函數(shù)")
},
updated: function () {
console.log("調(diào)用了updated鉤子函數(shù)");
},
});
app.msg = "數(shù)據(jù)被修改了";
</script>結(jié)果:

注意只有寫入模板的數(shù)據(jù)才會(huì)被追蹤
beforeDestroy和destroyed鉤子函數(shù)間的生命周期

beforeDestroy
銷毀前執(zhí)行($destroy方法被調(diào)用的時(shí)候就會(huì)執(zhí)行),一般在這里善后:清除計(jì)時(shí)器、清除非指令綁定的事件等等…’)
destroyed
銷毀后 (Dom元素存在,只是不再受vue控制),卸載watcher,事件監(jiān)聽,子組件
總結(jié)
- beforecreate : 可以在這加個(gè)loading事件
- created :在這結(jié)束loading,還做一些初始數(shù)據(jù)的獲取,實(shí)現(xiàn)函數(shù)自-執(zhí)行
- mounted : 在這發(fā)起后端請(qǐng)求,拿回?cái)?shù)據(jù),配合路由鉤子做一些事情
- beforeDestroy: 你確認(rèn)刪除XX嗎?
- destroyed :當(dāng)前組件已被刪除,清空相關(guān)內(nèi)容
到此這篇關(guān)于Vue生命周期深入分析總結(jié)的文章就介紹到這了,更多相關(guān)Vue生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
html頁面引入vue組件之http-vue-loader.js解讀
這篇文章主要介紹了html頁面引入vue組件之http-vue-loader.js解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法
這篇文章主要介紹了nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11
vue el-checkbox實(shí)現(xiàn)全選單選方式
這篇文章主要介紹了vue el-checkbox實(shí)現(xiàn)全選單選方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
vue+springboot實(shí)現(xiàn)登錄功能
這篇文章主要為大家詳細(xì)介紹了vue+springboot實(shí)現(xiàn)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
vue刷新頁面時(shí)去閃爍提升用戶體驗(yàn)效果的實(shí)現(xiàn)方法
這篇文章主要介紹了vue刷新頁面時(shí)去閃爍提升體驗(yàn)方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12

