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ī)會,不會觸發(fā)其余的鉤子函數(shù),通常能夠在這里作初始數(shù)據(jù)。這個(gè)階段操作DOM是不奏效的。
mounted
載入后html已經(jīng)渲染(ajax請求能夠放在這個(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ī)制會從新構(gòu)建虛擬dom與上一次的虛擬dom樹利用diff算法進(jìn)行對比以后從新渲染。
updated
數(shù)據(jù)已經(jīng)更改完成,dom也從新render完成。
第三節(jié)-銷毀實(shí)例
Vm.$destroy():銷毀后自定義事件會失效,但原生DOM事件依然有效。銷毀后會調(diào)用下面兩個(gè)鉤子。
beforeDestroy
銷毀前執(zhí)行($destroy方法被調(diào)用的時(shí)候就會執(zhí)行),通常在這里善后:清除計(jì)時(shí)器、清除非指令綁定的事件等等…’)。
destroyed
銷毀后 (Dom元素存在,只是再也不受vue控制),卸載watcher,事件監(jiān)聽,子組件
簡單的對生命周期總結(jié)
常用的生命周期鉤子
1.mounted: 發(fā)送ajax請求、啟動(dòng)定時(shí)器、綁定自定義事件、訂閱消息等【初始化操作】。
2.beforeDestroy: 清除定時(shí)器、解綁自定義事件、取消訂閱消息等【收尾工作】。
關(guān)于銷毀Vue實(shí)例
1.銷毀后借助Vue開發(fā)者工具看不到任何信息。
2.銷毀后自定義事件會失效,但原生DOM事件依然有效。
3.一般不會在beforeDestroy操作數(shù)據(jù),因?yàn)榧幢悴僮鲾?shù)據(jù),也不會再觸發(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控制臺 直接輸入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間的生命周期
對于created鉤子函數(shù)和beforeMount有判斷:
el選項(xiàng)對生命周期影響
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)先級:
<h1>測試template和HTML的優(yōu)先級</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í)例對象中有template參數(shù)選項(xiàng),則將其作為模板編譯成render函數(shù)
- 如果沒有template參數(shù)選項(xiàng),則將外部的HTML作為模板編譯(template),也就是說,template參數(shù)選項(xiàng)的優(yōu)先級要比外部的HTML高
- 如果1,2條件都不具備,則報(bào)錯(cuò)
注意
Vue需要通過el去找對應(yīng)的template,Vue實(shí)例通過el的參數(shù),首先找自己有沒有template,如果沒有再去找外部的html,找到后將其編譯成render函數(shù)。
也可以直接調(diào)用render選項(xiàng),優(yōu)先級: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ī)會,不會觸發(fā)其他的鉤子函數(shù),一般可以在這里做初始數(shù)據(jù)的獲取。
Mount
載入后html已經(jīng)渲染(ajax請求可以放在這個(gè)函數(shù)中),把vue實(shí)例中的data里的message掛載到DOM節(jié)點(diǎn)中去
這里兩個(gè)鉤子函數(shù)間是載入數(shù)據(jù)。
beforeUpdate鉤子函數(shù)和updated鉤子函數(shù)間的生命周期
在Vue中,修改數(shù)據(jù)會導(dǎo)致重新渲染,依次調(diào)用beforeUpdate鉤子函數(shù)和updated鉤子函數(shù)
如果待修改的數(shù)據(jù)沒有載入模板中,不會調(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ù),會調(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ù)才會被追蹤
beforeDestroy和destroyed鉤子函數(shù)間的生命周期
beforeDestroy
銷毀前執(zhí)行($destroy方法被調(diào)用的時(shí)候就會執(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ā)起后端請求,拿回?cái)?shù)據(jù),配合路由鉤子做一些事情
- beforeDestroy: 你確認(rèn)刪除XX嗎?
- destroyed :當(dāng)前組件已被刪除,清空相關(guān)內(nèi)容
到此這篇關(guān)于Vue生命周期深入分析總結(jié)的文章就介紹到這了,更多相關(guān)Vue生命周期內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
html頁面引入vue組件之http-vue-loader.js解讀
這篇文章主要介紹了html頁面引入vue組件之http-vue-loader.js解讀,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法
這篇文章主要介紹了nuxt.js中間件實(shí)現(xiàn)攔截權(quán)限判斷的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11vue el-checkbox實(shí)現(xiàn)全選單選方式
這篇文章主要介紹了vue el-checkbox實(shí)現(xiàn)全選單選方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03vue+springboot實(shí)現(xiàn)登錄功能
這篇文章主要為大家詳細(xì)介紹了vue+springboot實(shí)現(xiàn)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08vue刷新頁面時(shí)去閃爍提升用戶體驗(yàn)效果的實(shí)現(xiàn)方法
這篇文章主要介紹了vue刷新頁面時(shí)去閃爍提升體驗(yàn)方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12