當面試官問:“談談你對vue的生命週期的理解”,聽到這句話你是不是心裡暗自竊喜:這也太容易了吧,不就是beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed 這幾個鉤子函式麼,建立=>掛載=>更新=>銷燬,So easy !!!
非也非也。如果你只是簡單羅列出這幾個鉤子函式的名稱,不具體深入闡述的話,你這樣的回答很難令面試官滿意。如何才能以點帶面深入闡述自己對vue的生命週期理解,從而讓面試官對你留下好印象呢?
別急,閏土大叔來告訴你,下次再碰到這個問題,你可以直接甩給面試官下面這張Image就OK了~
當然,甩張Image給面試官這句話肯定是開玩笑的(適度幽默,緩解緊張氣氛)。不過這張流程圖還是有用的,因為它是我從Vue官網上拷貝下來的,只要你能理解了這張圖,也就對Vue的生命週期有了一個大致的瞭解。那麼接下來,閏土大叔將手摸手教你如何深入淺出地說出令面試官滿意的、有亮點的回答。
在談到Vue的生命週期的時候,我們首先需要建立一個例項,也就是在 new Vue ( ) 的物件過程當中,首先執行了init(init是vue元件裡面預設去執行的),在init的過程當中首先呼叫了beforeCreate,然後在injections(注射)和reactivity(反應性)的時候,它會再去呼叫created。所以在init的時候,事件已經呼叫了,我們在beforeCreate的時候千萬不要去修改data裡面賦值的資料,最早也要放在created裡面去做(新增一些行為)。
當created完成之後,它會去判斷instance(例項)裡面是否含有“el”option(選項),如果沒有的話,它會呼叫vm.$mount(el)這個方法,然後執行下一步;如果有的話,直接執行下一步。緊接著會判斷是否含有“template”這個選項,如果有的話,它會把template解析成一個render function ,這是一個template編譯的過程,結果是解析成了render函式:
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的內容。
在使用.vue檔案開發的過程當中,我們在裡面寫了template模板,在經過了vue-loader的處理之後,就變成了render function,最終放到了vue-loader解析過的檔案裡面。這樣做有什麼好處呢?原因是由於在解析template變成render function的過程,是一個非常耗時的過程,vue-loader幫我們處理了這些內容之後,當我們在頁面上執行vue程式碼的時候,效率會變得更高。
beforeMount在有了render function的時候才會執行,當執行完render function之後,就會呼叫mounted這個鉤子,在mounted掛載完畢之後,這個例項就算是走完流程了。
後續的鉤子函式執行的過程都是需要外部的觸發才會執行。比如說有資料的變化,會呼叫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方法報錯的情況下它才會被呼叫。
寫在最後
這就是關於vue的生命週期的一個詳細的闡述,大家只需要記住在vue的生命週期裡有哪些鉤子函式,它們分別是在什麼情況下會被呼叫,以及其中的一些原理即可。
以後如果有人問你“如何解釋vue的生命週期才能令面試官滿意”這個問題,你可以直接把這篇文章甩給他就OK了。
最後祝所有面試的童鞋順利拿到OFFER!
歡迎關注我的後續文章,文章預告:
- eslint的錯誤修復小技巧
- 開發時服務端渲染的配置和原理
- 使用koa實現node server
- ......
- 如何使用pm2以及伺服器端的部署