個人對vue中生命週期的理解
雖然現在網上有一大堆關於vue生命週期的文章,但我總覺得還是自己再來一遍理解更深,當然,我也看了很多關於vue生命週期的文章才寫出我自己的理解,不妥之處,不吝賜教!
官方圖解
首先,走流程,上官方圖解,注意,是官方圖解!

生命鉤子函式
什麼叫鉤子函式?我認為,鉤子就是隨時可能或者有需要時掛到什麼東西上,從而引發一些流血事件的發生。顯而易見,vue中的生命鉤子函式,就是隨時或者說在達到某一階段或條件時去觸發的函式,目的就是為了完成一些動作或者事件。需要注意的是,所有的生命週期鉤子自動繫結 this 上下文到例項中,因此你可以訪問資料,對屬性和方法進行運算。
通常我們所說的生命週期分為8個:分別為在初始化例項時,預設呼叫的 beforeCreate 、 created 、 beforeMount 、 mounted 這四個鉤子函式,還有當更新資料時,更新之前會觸發 beforeUpdate 這個鉤子函式,更新完成之後,會觸發 updated 這個鉤子函式;當vue的例項銷燬時,會呼叫 beforeDestroy 和 destroyed 這兩個鉤子函式。除此之外還有不常用的 activated 、 deactivated 、 errorCaptured 這三個鉤子函式,下面我會結合官方圖解逐一說一下。(我是不是很囉嗦啊)
過程
首先我們需要建立一個例項 new Vue()
,也就是在這個過程當中,首先執行了init(init是vue元件裡面預設去執行的), init Events & Lifecycle
後先呼叫了beforeCreate,所以此時事件已經好了,也能開始使用生命週期函數了,然後繼續 init injections(注射) & reactivity(反應性)
,在例項建立完成後它會立即呼叫created。在這一步,例項已完成以下的配置:資料觀測 (data observer),屬性和方法的運算,watch/event 事件回撥。所以在init的時候,事件已經呼叫了,我們在beforeCreate的時候千萬不要去修改data裡面賦值的資料,最早也要放在created裡面去做(新增一些行為)。
當created完成之後,它會去判斷instance(例項)裡面是否含有“el”option(選項),如果沒有的話,它會等待我們呼叫vm.$mount(el)這個方法,然後執行下一步;如果有的話,直接執行下一步。緊接著會判斷是否含有“template”這個選項,如果有,把 template 解析成一個 render function。render 函式會用 template 中的 html 去覆蓋 html 中的 div 標籤。在使用 .vue 檔案進行開發的過程中,是沒有 template 的,我們在 .vue 檔案中寫的 template 都經過了 vue-loader 處理,直接變成了 render 函式,放在vue-loader 解析過的檔案中;這樣做的好處,把 template 解析成 render 函式,比較耗時,vue-loader處理後,我們在頁面上執行程式碼時,效率會變高。如果沒有,Compile el's outerHTML as template。
beforeMount在有了render函式的時候才會執行,此時vue例項的 $el
和data都初始化了,但還是掛載之前為虛擬的dom節點。然後繼續執行render函式。當執行完render函式之後,也就是el被新建立的 vm.$el
替換,並掛載到例項上去之後就會呼叫mounted這個鉤子,在mounted掛載完畢之後,這個例項就算是走完流程了,此時el也被掛載到了真實DOM上。但是它不會承諾所有的子元件也都一起被掛載。如果你希望等到整個檢視都渲染完畢,可以用 vm.$nextTick()
。後續幾個鉤子函式,都是通過外部觸發進行的。
當資料更新變化時,beforeUpdate 執行,然後 Virtual DOM re-render and patch
最後updated 執行。
當元件銷燬時,beforeDestroy 執行,然後 Teardown watchers,child comonents and event listeners
,最後destroyed 執行。
然後說一下另外三個不常用的鉤子,首先 activated 、 deactivated 是和vue中一個原生的元件 keep-alive 有關係,當keep-alive元件啟用時呼叫activated鉤子。keep-alive 元件停用時呼叫deactivated鉤子。鉤子 errorCaptured 是當捕獲一個來自子孫元件的錯誤時被呼叫。此鉤子會收到三個引數:錯誤物件、發生錯誤的元件例項以及一個包含錯誤來源資訊的字串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播。
現在大家可以用程式碼測試一下鉤子函式的觸發順序,還有data資料和el渲染完畢的時間。
<div id="app"> <input type="text" v-model="msg">//測試資料更新時的鉤子 {{msg}} </div> let vm = new Vue({ el:"#app", data: { msg:"data資料", }, methods:{ fn(){ this.msg="改變data資料" } }, beforeCreate(){ // 建立之前;無法獲取響應資料 console.log("beforeCreate","data:"+this.msg,"el:"+this.$el); }, created(){ // 建立之後 console.log("created","data:"+this.msg,"el:"+this.$el); }, beforeMount(){ // 掛載前 console.log("beforeMount","data:"+this.msg,"el:"+this.$el); }, mounted(){ // 掛載後 console.log("mounted","data:"+this.msg,"el:"+this.$el); }, beforeUpdate(){ // 資料更新之前 console.log("beforeUpdate","data:"+this.msg,"el:"+this.$el); }, updated(){ // 資料更新完成之後; console.log("updated","data:"+this.msg,"el:"+this.$el); }, beforeDestroy(){ // 銷燬之前 console.log("beforeDestroy","data:"+this.msg,"el:"+this.$el); }, destroyed(){ // 銷燬之後 console.log("destroyed","data:"+this.msg,"el:"+this.$el); } }); // vm.$destroy();//測試銷燬元件呼叫的鉤子 //測試結果 //初始化過程 beforeCreate data:undefined el:undefined created data:data資料 el:undefined beforeMount data:data資料 el:[object HTMLDivElement] mounted data:data資料 el:[object HTMLDivElement] //資料更新後 beforeUpdate data:data資料更新 el:[object HTMLDivElement] updated data:data資料更新 el:[object HTMLDivElement] //資料銷燬後 beforeDestroy data:data資料 el:[object HTMLDivElement] destroyed data:data資料 el:[object HTMLDivElement] 複製程式碼