https://juejin.im/post/5ad10800f265da23826e681e
beforeCreate裆泳、created品洛、beforeMount、mounted括儒、beforeUpdate选侨、updated、beforeDestroy抽碌、destroyed 創(chuàng)建=>掛載=>更新=>銷毀
beforeCreate:
el? ? : undefined
data? : undefined
message: undefined復(fù)制代碼
created:
el? ? : undefined
data? : [object Object]
message: hi復(fù)制代碼
beforeMount:
el? ? : [object HTMLDivElement]
{{ message }}
mounted:
el? ? : [object HTMLDivElement]
<div id="app"><p>hi</p></div>
data? : [object Object]
message: hi
在談到Vue的生命周期的時(shí)候悍赢,我們首先需要?jiǎng)?chuàng)建一個(gè)實(shí)例,也就是在 new Vue ( ) 的對(duì)象過(guò)程當(dāng)中货徙,首先執(zhí)行了init(init是vue組件里面默認(rèn)去執(zhí)行的)左权,在init的過(guò)程當(dāng)中首先調(diào)用了beforeCreate,然后在injections(注射)和reactivity(反應(yīng)性)的時(shí)候痴颊,它會(huì)再去調(diào)用created赏迟。所以在init的時(shí)候,事件已經(jīng)調(diào)用了蠢棱,我們?cè)赽eforeCreate的時(shí)候千萬(wàn)不要去修改data里面賦值的數(shù)據(jù)锌杀,最早也要放在created里面去做(添加一些行為)甩栈。
當(dāng)created完成之后,它會(huì)去判斷instance(實(shí)例)里面是否含有“el”option(選項(xiàng))糕再,如果沒(méi)有的話量没,它會(huì)調(diào)用vm.$mount(el)這個(gè)方法,然后執(zhí)行下一步突想;如果有的話殴蹄,直接執(zhí)行下一步。緊接著會(huì)判斷是否含有“template”這個(gè)選項(xiàng)蒿柳,如果有的話饶套,它會(huì)把template解析成一個(gè)render function ,這是一個(gè)template編譯的過(guò)程垒探,結(jié)果是解析成了render函數(shù):
render (h) {
? return h('div', {}, this.text)
}
復(fù)制代碼解釋一下,render函數(shù)里面的傳參h就是Vue里面的createElement方法怠李,return返回一個(gè)createElement方法圾叼,其中要傳3個(gè)參數(shù),第一個(gè)參數(shù)就是創(chuàng)建的div標(biāo)簽捺癞;第二個(gè)參數(shù)傳了一個(gè)對(duì)象夷蚊,對(duì)象里面可以是我們組件上面的props,或者是事件之類的東西髓介;第三個(gè)參數(shù)就是div標(biāo)簽里面的內(nèi)容惕鼓,這里我們指向了data里面的text。
使用render函數(shù)的結(jié)果和我們之前使用template解析出來(lái)的結(jié)果是一樣的唐础。render函數(shù)是發(fā)生在beforeMount和mounted之間的箱歧,這也從側(cè)面說(shuō)明了,在beforeMount的時(shí)候一膨,$el還只是我們?cè)贖TML里面寫的節(jié)點(diǎn)呀邢,然后到mounted的時(shí)候,它就把渲染出來(lái)的內(nèi)容掛載到了DOM節(jié)點(diǎn)上豹绪。這中間的過(guò)程其實(shí)是執(zhí)行了render function的內(nèi)容价淌。
在使用.vue文件開(kāi)發(fā)的過(guò)程當(dāng)中,我們?cè)诶锩鎸懥藅emplate模板瞒津,在經(jīng)過(guò)了vue-loader的處理之后蝉衣,就變成了render function,最終放到了vue-loader解析過(guò)的文件里面巷蚪。這樣做有什么好處呢病毡?原因是由于在解析template變成render function的過(guò)程,是一個(gè)非常耗時(shí)的過(guò)程钓辆,vue-loader幫我們處理了這些內(nèi)容之后剪验,當(dāng)我們?cè)陧?yè)面上執(zhí)行vue代碼的時(shí)候肴焊,效率會(huì)變得更高。
beforeMount在有了render function的時(shí)候才會(huì)執(zhí)行功戚,當(dāng)執(zhí)行完render function之后娶眷,就會(huì)調(diào)用mounted這個(gè)鉤子,在mounted掛載完畢之后啸臀,這個(gè)實(shí)例就算是走完流程了届宠。
后續(xù)的鉤子函數(shù)執(zhí)行的過(guò)程都是需要外部的觸發(fā)才會(huì)執(zhí)行。比如說(shuō)有數(shù)據(jù)的變化乘粒,會(huì)調(diào)用beforeUpdate豌注,然后經(jīng)過(guò)Virtual DOM,最后updated更新完畢灯萍。當(dāng)組件被銷毀的時(shí)候轧铁,它會(huì)調(diào)用beforeDestory,以及destoryed旦棉。
這就是vue實(shí)例從新建到銷毀的一個(gè)完整流程齿风,以及在這個(gè)過(guò)程中它會(huì)觸發(fā)哪些生命周期的鉤子函數(shù)。那說(shuō)到這兒绑洛,可能很多童鞋會(huì)問(wèn)救斑,鉤子函數(shù)是什么意思?
鉤子函數(shù)真屯,其實(shí)和回調(diào)是一個(gè)概念脸候,當(dāng)系統(tǒng)執(zhí)行到某處時(shí),檢查是否有hook绑蔫,有則回調(diào)运沦。說(shuō)的更直白一點(diǎn),每個(gè)組件都有屬性晾匠,方法和事件茶袒。所有的生命周期都?xì)w于事件,在某個(gè)時(shí)刻自動(dòng)執(zhí)行凉馆。
其實(shí)薪寓,當(dāng)你跟面試官闡述到這兒的時(shí)候,面試官基本上已經(jīng)滿意你的回答了澜共,隱約看到了你的技術(shù)功底向叉。當(dāng)然,如果你還想更進(jìn)一步嗦董,讓面試官對(duì)你刮目相看母谎,達(dá)到加分的效果,你還可以這樣說(shuō):
在這個(gè)過(guò)程當(dāng)中京革,Vue為我們提供了renderError方法奇唤,這個(gè)方法只有在開(kāi)發(fā)的時(shí)候它才會(huì)被調(diào)用幸斥,在正式打包上線的過(guò)程當(dāng)中,它是不會(huì)被調(diào)用的咬扇。它主要是幫助我們調(diào)試render里面的一些錯(cuò)誤甲葬。
renderError (h, err) {
? return h('div', {}, err.stack)
}
復(fù)制代碼有且只有當(dāng)render方法里面報(bào)錯(cuò)了,才會(huì)執(zhí)行renderError方法懈贺。
所以我們主動(dòng)讓render函數(shù)報(bào)個(gè)錯(cuò):
render (h) {
? throw new TypeError('render error')
}
復(fù)制代碼
如圖所示经窖,渲染出來(lái)的就是Error信息了。還有一點(diǎn)梭灿,renderError只有在本組件的render方法報(bào)錯(cuò)的情況下它才會(huì)被調(diào)用画侣。
beforeCreate中拿不到任何數(shù)據(jù),它在實(shí)例初始化之后堡妒,數(shù)據(jù)觀測(cè) (data observer) 和 event/watcher 事件配置之前被調(diào)用配乱。
created中已經(jīng)可以拿到data中的數(shù)據(jù)了,但是dom還沒(méi)有掛載涕蚤。會(huì)判斷有無(wú)el宪卿,如果沒(méi)有el則停止后面的模板掛載。
在實(shí)例創(chuàng)建完成后被立即調(diào)用万栅。在這一步,實(shí)例已完成以下的配置:數(shù)據(jù)觀測(cè) (data observer)西疤,屬性和方法的運(yùn)算烦粒,watch/event 事件回調(diào)。
使用場(chǎng)景:ajax請(qǐng)求和頁(yè)面初始化
beforeMount 和 created 拿到的數(shù)據(jù)相同 在掛載開(kāi)始之前被調(diào)用:相關(guān)的 render 函數(shù)首次被調(diào)用代赁。
mounted中el被創(chuàng)建dom已經(jīng)更新扰她,vue實(shí)例對(duì)象中有template參數(shù)選項(xiàng),則將其作為模板編譯成render函數(shù)芭碍,編譯優(yōu)先級(jí)render函數(shù)選項(xiàng) > template選項(xiàng)
使用場(chǎng)景:常用于獲取VNode信息和操作徒役,ajax請(qǐng)求
注意 mounted 不會(huì)承諾所有的子組件也都一起被掛載。如果你希望等到整個(gè)視圖都渲染完畢窖壕,可以用 vm.$nextTick 替換掉 mounted
由于beforeUpdate和updated使用的比較少忧勿,一般用計(jì)算屬性和watch代替所以在此不在說(shuō)明
destroyed Vue 實(shí)例銷毀后調(diào)用。調(diào)用后瞻讽,Vue 實(shí)例指示的所有東西都會(huì)解綁定鸳吸,所有的事件監(jiān)聽(tīng)器會(huì)被移除,所有的子實(shí)例也會(huì)被銷毀速勇。
“你不需要立馬弄明白所有的東西晌砾,不過(guò)隨著你的不斷學(xué)習(xí)和使用,它的參考價(jià)值會(huì)越來(lái)越高烦磁⊙伲”
現(xiàn)在項(xiàng)目中遇到了哼勇,好好回頭總結(jié)一波Vue生命周期,以后用到的時(shí)候再來(lái)翻翻呕乎。
啥叫Vue生命周期积担?
每個(gè) Vue 實(shí)例在被創(chuàng)建時(shí)都要經(jīng)過(guò)一系列的初始化過(guò)程。
例如:從開(kāi)始創(chuàng)建楣嘁、初始化數(shù)據(jù)磅轻、編譯模板、掛載Dom逐虚、數(shù)據(jù)變化時(shí)更新DOM聋溜、卸載等一系列過(guò)程。
我們稱這一系列的過(guò)程就是Vue的生命周期叭爱。
通俗說(shuō)就是Vue實(shí)例從創(chuàng)建到銷毀的過(guò)程撮躁,就是生命周期。
同時(shí)在這個(gè)過(guò)程中也會(huì)運(yùn)行一些叫做生命周期鉤子的函數(shù)买雾,這給了用戶在不同階段添加自己的代碼的機(jī)會(huì)把曼,利用各個(gè)鉤子來(lái)完成我們的業(yè)務(wù)代碼。
啥也不說(shuō)漓穿,先來(lái)個(gè)干貨
這是對(duì)于Vue生命周期嗤军,官網(wǎng)給的那張圖的標(biāo)注圖,圖片網(wǎng)上看到的晃危,我覺(jué)得標(biāo)注地很nice叙赚,建議一步步仔細(xì)看完圖片,然后把圖片自己悄悄保存下來(lái)僚饭,對(duì)照著圖片的內(nèi)容看第二部分的舉例說(shuō)明震叮。
我相信程序員看代碼比看文字更容易理解
對(duì)照著上圖標(biāo)注的內(nèi)容,我們一個(gè)鉤子一個(gè)鉤子地舉例說(shuō)明鳍鸵。
作者:Sadhu
鏈接:https://juejin.im/post/5bd6962e51882558bd3f0696
來(lái)源:掘金
著作權(quán)歸作者所有苇瓣。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處偿乖。