當面試官問:「談談你對vue的生命週期的理解」,聽到這句話你是否是內心暗自竊喜:這也太容易了吧,不就是beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed 這幾個鉤子函數麼,建立=>掛載=>更新=>銷燬,So easy !!!vue
非也非也。若是你只是簡單羅列出這幾個鉤子函數的名稱,不具體深刻闡述的話,你這樣的回答很難令面試官滿意。如何才能以點帶面深刻闡述本身對vue的生命週期理解,從而讓面試官對你留下好印象呢?react
別急,閏土大叔來告訴你,下次再碰到這個問題,你能夠直接甩給面試官下面這張Image就OK了~面試
固然,甩張Image給面試官這句話確定是開玩笑的(適度幽默,緩解緊張氣氛)。不過這張流程圖仍是有用的,由於它是我從Vue官網上拷貝下來的,只要你能理解了這張圖,也就對Vue的生命週期有了一個大體的瞭解。那麼接下來,閏土大叔將手摸手教你如何深刻淺出地說出令面試官滿意的、有亮點的回答。函數
在談到Vue的生命週期的時候,咱們首先須要建立一個實例,也就是在 new Vue ( ) 的對象過程中,首先執行了init(init是vue組件裏面默認去執行的),在init的過程中首先調用了beforeCreate,而後在injections(注射)和reactivity(反應性)的時候,它會再去調用created。因此在init的時候,事件已經調用了,咱們在beforeCreate的時候千萬不要去修改data裏面賦值的數據,最先也要放在created裏面去作(添加一些行爲)。this
當created完成以後,它會去判斷instance(實例)裏面是否含有「el」option(選項),若是沒有的話,它會調用vm.$mount(el)這個方法,而後執行下一步;若是有的話,直接執行下一步。緊接着會判斷是否含有「template」這個選項,若是有的話,它會把template解析成一個render function ,這是一個template編譯的過程,結果是解析成了render函數:spa
render (h) { return h('div', {}, this.text) }
解釋一下,render函數裏面的傳參h就是Vue裏面的createElement方法,return返回一個createElement方法,其中要傳3個參數,第一個參數就是建立的div標籤;第二個參數傳了一個對象,對象裏面能夠是咱們組件上面的props,或者是事件之類的東西;第三個參數就是div標籤裏面的內容,這裏咱們指向了data裏面的text。調試
使用render函數的結果和咱們以前使用template解析出來的結果是同樣的。render函數是發生在beforeMount和mounted之間的,這也從側面說明了,在beforeMount的時候,$el還只是咱們在HTML裏面寫的節點,而後到mounted的時候,它就把渲染出來的內容掛載到了DOM節點上。這中間的過程實際上是執行了render function的內容。code
在使用.vue文件開發的過程中,咱們在裏面寫了template模板,在通過了vue-loader的處理以後,就變成了render function,最終放到了vue-loader解析過的文件裏面。這樣作有什麼好處呢?緣由是因爲在解析template變成render function的過程,是一個很是耗時的過程,vue-loader幫咱們處理了這些內容以後,當咱們在頁面上執行vue代碼的時候,效率會變得更高。對象
beforeMount在有了render function的時候纔會執行,當執行完render function以後,就會調用mounted這個鉤子,在mounted掛載完畢以後,這個實例就算是走完流程了。blog
後續的鉤子函數執行的過程都是須要外部的觸發纔會執行。好比說有數據的變化,會調用beforeUpdate,而後通過Virtual DOM,最後updated更新完畢。當組件被銷燬的時候,它會調用beforeDestory,以及destoryed。
這就是vue實例重新建到銷燬的一個完整流程,以及在這個過程當中它會觸發哪些生命週期的鉤子函數。那說到這兒,可能不少童鞋會問,鉤子函數是什麼意思?
鉤子函數,其實和回調是一個概念,當系統執行到某處時,檢查是否有hook,有則回調。說的更直白一點,每一個組件都有屬性,方法和事件。全部的生命週期都歸於事件,在某個時刻自動執行。
其實,當你跟面試官闡述到這兒的時候,面試官基本上已經滿意你的回答了,隱約看到了你的技術功底。固然,若是你還想更進一步,讓面試官對你另眼相看,達到加分的效果,你還能夠這樣說:
在這個過程中,Vue爲咱們提供了renderError方法,這個方法只有在開發的時候它纔會被調用,在正式打包上線的過程中,它是不會被調用的。它主要是幫助咱們調試render裏面的一些錯誤。
renderError (h, err) { return h('div', {}, err.stack) }
有且只有當render方法裏面報錯了,纔會執行renderError方法。
因此咱們主動讓render函數報個錯:
render (h) { throw new TypeError('render error') }
如圖所示,渲染出來的就是Error信息了。還有一點,renderError只有在本組件的render方法報錯的狀況下它纔會被調用。