Vue實例有一個完整的生命週期,也就是從開始創建、初始化數據、編譯模板、掛載Dom、渲染→更新→渲染、銷燬等一系列過程,我們稱這是Vue的生命週期。通俗說就是Vue實例從創建到銷燬的過程,就是生命週期。同時在這個過程中也會運行一些叫做生命週期鉤子的函數,這給了用戶在不同階段添加自己的代碼的機會。
(一)生命週期鉤子 按順序依次爲:
1. beforeCreate()
在實例初始化事件和生命週期之後、數據觀測和事件配置之前被調用。
此時,組件的選項對象還未創建,date、method和el均沒有初始化,因此無法訪問到數據data, methods、computed等上的方法和數據以及真實的DOM。一般不做掛載數據,綁定事件等操作。
2. created()
在實例已經創建完成之後被調用。
此時,實例已完成以下配置:數據觀測、屬性和方法的運算,watch/event事件回調,完成了data 數據的初始化。 然而,el沒有還未初始化,掛載階段還沒有開始, $el屬性目前不可見。
這是一個常用的生命週期,可以調用methods中的方法,改變data中的數據,並且修改可以通過vue的響應式綁定體現在頁面上,獲取computed中的計算屬性等等。
3. beforeMount()
在掛載開始之前被調用,相關的render函數首次被調用(虛擬DOM)。
此時,實例已完成以下的配置: 編譯模板,把data裏面的數據和模板生成html,完成了el和data 初始化,然而,還沒有掛載html到頁面上。
該鉤子在服務端渲染期間不被調用。
4. mounted()
掛載完成,也就是模板中的HTML渲染到HTML頁面中,此時一般可以做一些ajax操作。
該鉤子在服務端渲染期間不被調用。
5. beforeUpdate()
在數據更新之前被調用,發生在虛擬DOM重新渲染和打補丁之前,可以在該鉤子中進一步地更改狀態,不會觸發附加地重渲染過程。
該鉤子在服務端渲染期間不被調用。
6. updated()
在由於數據更改導致地虛擬DOM重新渲染和打補丁之後調用,調用時,組件DOM已經更新,所以可以執行依賴於DOM的操作,然後在大多是情況下,應該避免在此期間更改狀態,因爲這可能會導致更新無限循環。
該鉤子在服務器端渲染期間不被調用
7. beforeDestroy()
在實例銷燬之前調用,實例仍然完全可用。
此時,還可以用this來獲取實例,一般在這一步做一些重置的操作,比如清除掉組件中的定時器 和 監聽的dom事件。
該鉤子在服務端渲染期間不被調用。
8. destroy()
在實例銷燬之後調用,調用後,所以的事件監聽器會被移出,所有的子實例也會被銷燬,該鉤子在服務器端渲染期間不被調用。
用更直觀的圖說明:
-
生命週期:
-
創建階段:
-
更新階段:
-
銷燬階段:
注意點: -
不要在選項屬性或回調上使用箭頭函數,比如
created: () => console.log(this.a)
或vm.$watch('a', newValue => this.myMethod())
。因爲箭頭函數並沒有this
,this
會作爲變量一直向上級詞法作用域查找,直至找到爲止,經常導致錯誤。 -
如果不指定 el 選項,就只會執行 beforeCreate() 、created()。
-
做一些和DOM有關的操作時,一般放在mounted()
-
和數據有關的操作一般放在created()或mounted()
-
beforeCreate()、created()、beforeMount()、mounted()在組件生命週期中只執行一次。
10. Vue實例和子組件之間的生命週期
在Vue中,由於父元素的template模板嵌套了子元素,因此在編譯模板時,會先進入到父元素的template,然後層層遞歸進行子元素的模板編譯。
- 在創建時,父子組件的生命週期是:
父組件beforeCreated -> 父組件created -> 父組件beforeMounted -> 子組件beforeCreated -> 子組件created -> 子組件beforeMounted -> 子組件mounted -> 父組件mounted。 - 在銷燬時,父子組件的生命週期是:
父組件beforeDestory -> 子組件beforeDestoryed -> 子組件destoryed -> 父組件destoryed
總之記住,父子組件的生命週期遵循:由外到內,再由內到外
(二)官方的生命週期圖示
參考鏈接: