文章目錄
- 生命周期
- vue2.0生命周期
- 1.圖示
- 2.生命周期解釋說明
- 3.代碼示例
- vue3.0生命周期
- 1.圖示
- 2.生命周期解釋說明
- 3.代碼示例
- 父子組件中生命周期執行順序
- v.3和v2.0生命周期對比
生命周期
每個 Vue 組件實例在創建時都需要經歷一系列的初始化步驟,比如設置好數據偵聽,編譯模板,掛載實例到 DOM,以及在數據改變時更新 DOM。在此過程中,它也會運行被稱為生命周期鉤子的函數,在特定階段運行自己的代碼。
vue2.0生命周期
1.圖示
2.生命周期解釋說明
vue2在第一次頁面加載會觸發beforeCreate created beforeMount mounted四個鉤子函數,DOM渲染在mounted這個周期就已經完成
- **創建階段:從創建Vue實例開始到模版渲染成HTML結束
- beforeCreate:在實例被創建之初,完成數據觀測和event/eventBus事件配置等初始化任務之前調用。
- created:實例已經完成了數據觀測等初始化任務,意味著以下內容已被配置完畢:數據偵聽、計算屬性、方法、事件/偵聽器的回調函數。然而,掛載階段還沒開始,DOM元素并沒有生成,且
$el property
目前尚不可用,無法訪問。 - beforeMount:在DOM掛載之前調用,在此期間可以對DOM進行處理,但還未能訪問到DOM元素,相關的 render 函數首次被調用,此時是虛擬DOM。該鉤子在服務器端渲染期間不被調用。
- mounted:DOM掛載完成后調用,可以訪問到DOM元素、實例屬性和方法,并可以與后端請求數據和操作DOM。注意:mounted 不會保證所有的子組件也都被掛載完成。如果你希望等到整個視圖都渲染完畢再執行某些操作,可以在 mounted 內部使用 vm.$nextTick
- 更新階段: 當組件依賴的數據發生變化時,需要重新渲染組件,這個過程也涉及到一系列的生命周期函數
- beforeUpdate:在數據發生改變后,DOM 被更新之前被調用。這里適合在現有 DOM 將要被更新之前訪問它,比如移除手動添加的事件監聽器。 注:該鉤子在服務器端渲染期間不被調用,因為只有初次渲染會在服務器端進行。
- updated:在數據更改導致的虛擬 DOM 重新渲染和更新完畢之后被調用。
當這個鉤子被調用時,組件 DOM 已經更新,可以執行依賴于 DOM 的操作。
然而在大多數情況下,應該避免在此期間更改狀態。
如果要相應狀態改變,通常最好使用計算屬性或 watcher 取而代之。
注意:updated 不會保證所有的子組件也都被重新渲染完畢。如果你希望等到整個視圖都渲染完畢,可以在 updated 里使用 vm.$nextTick
- 卸載階段: 當組件不再需要的時候,需要進行卸載操作,也會觸發一系列的生命周期函數:
- beforeDestroy:在實例銷毀之前調用。這個階段可以進行一些清除工作,比如清除事件監聽器或取消定時器。
- destroyed:實例銷毀后調用。該鉤子被調用后,對應 Vue 實例的所有指令都被解綁,所有的事件監聽器被移除,所有的子實例也都被銷毀。
- **KeepAlives緩存生命周期:**當組件在
<keep-alive>
內被切換,它的 activated 和 deactivated 這兩個生命周期鉤子函數將會被對應執行。- deactivated 被 keep-alive 緩存的組件失活時調用。
- activated 被 keep-alive 緩存的組件激活時調用。
- 組件中捕獲錯誤周期: 當捕獲一個來自子孫組件的異常時激活鉤子函數。
- errorCaptured:在捕獲一個來自后代組件的錯誤時被調用。此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播。
可以在此鉤子中修改組件的狀態。
因此在捕獲錯誤時,在模板或渲染函數中有一個條件判斷來繞過其它內容就很重要;不然該組件可能會進入一個無限的渲染循環。
3.代碼示例
<template><div><h2>{{title}}</h2><ul><h3>{{num}}</h3><button @click="num++">操作數據</button></ul></div>
</template><script>export default {data() {return {title: "Hello Vue!",num:0};},methods:{show(){console.log('我是show方法');},},beforeCreate() {console.log("-------beforeCreate--------");/* beforeCreate鉤子函數在組件創建之前被調用,該函數被調用的時候,props,data,mehtods都沒有被創建該組件的用處不是很大,但地位很高。*/console.log("data", this.msg);//console.log('props',this.title);//this.show();},created(){console.log("-------created--------");/* created鉤子函數是在init Injections&Activitys之后被調用,此時已經完成props,data,methods的創建,所以在此處調用這些方法或方法模板或者DOM還沒有被創建此鉤子函數重要的用途是用來向服務端獲取網絡請求數據在此鉤子函數之后的鉤子中也能完成網絡請求,但是一般都是在這里完成最佳*/this.show();},beforeMount(){console.log('-------beforeMount--------');/* 該鉤子函數之前的環節主要工作是將數據讀取后填充到模板上,之后有讀到內存中暫時存儲*/console.log('dom',document.querySelector('h2')); },mounted(){console.log('-------mounted--------');console.log('dom',document.querySelector('h2'));},beforeUpdate(){console.log('---------beforeUpdate-----------');/* beforeUpdate鉤子函數中的特征數據已經變了但是頁面還沒來得及渲染數據是新的,而頁面是舊的*/console.log('data',this.num);console.log('dom',document.querySelector('h3').innerHTML);},updated(){console.log('---------updated-----------');console.log('data',this.num);console.log('dom',document.querySelector('h3').innerHTML);},beforeDestroy(){console.log('-----------beforeDestroy--------------');/* 此處是準備在銷毀之前調用的鉤子此處特征,數據props,data,methods都可以訪問,但是DOM已經被移除了*/console.log('data',this.num);// console.log('dom',document.querySelector('h3').innerHTML);},destroyed(){console.log('-----------destroyed--------------');console.log('data',this.num);}
};
</script><style>
</style>
vue3.0生命周期
1.圖示
2.生命周期解釋說明
- **創建階段:**從創建Vue實例開始到模版渲染成HTML結束
- setup() : 開始創建組件之前,在 beforeCreate 和 created 之前執行,創建的是 data 和 method
- onBeforeMount() : 注冊一個鉤子,在組件被掛載之前被調用。
當這個鉤子被調用時,組件已經完成了其響應式狀態的設置,但還沒有創建 DOM 節點。它即將首次執行 DOM 渲染過程。
- onMounted() 注冊一個回調函數,在組件掛載完成后執行。通常用于執行需要訪問組件所渲染的 DOM 樹相關的副作用,或是在服務端渲染應用中用于確保 DOM 相關代碼僅在客戶端執行。
被視為掛載完成
- 其所有同步子組件都已經被掛載 (不包含異步組件或
<Suspense>
樹內的組件)。 - 其自身的 DOM 樹已經創建完成并插入了父容器中。注意僅當根容器在文檔中時,才可以保證組件 DOM 樹也在文檔中。
- 其所有同步子組件都已經被掛載 (不包含異步組件或
- 更新階段: 當組件依賴的數據發生變化時,需要重新渲染組件,這個過程也涉及到一系列的生命周期函數
- onBeforeUpdate() : 注冊一個鉤子,在組件即將因為響應式狀態變更而更新其 DOM 樹之前調用。
這個鉤子可以用來在 Vue 更新 DOM 之前訪問 DOM 狀態。在這個鉤子中更改狀態也是安全的。
- onUpdated() : 注冊一個回調函數,在組件因為響應式狀態變更而更新其 DOM 樹之后調用。
- 父組件的更新鉤子將在其子組件的更新鉤子之后調用。
- 鉤子會在組件的任意 DOM 更新后被調用,這些更新可能是由不同的狀態變更導致的,因為多個狀態變更可以在同一個渲染周期中批量執行 (考慮到性能因素)。
如果你需要在某個特定的狀態更改后訪問更新后的 DOM,請使用 nextTick() 作為替代。 - 注:不要在onUpdated鉤子中更改組件的狀態,這可能會導致無限的更新循環!
- onBeforeUpdate() : 注冊一個鉤子,在組件即將因為響應式狀態變更而更新其 DOM 樹之前調用。
- 卸載階段: 當組件不再需要的時候,需要進行卸載操作,也會觸發一系列的生命周期函數:
- onBeforeUnmount() : 注冊一個鉤子,在組件實例被卸載之前調用。當這個鉤子被調用時,組件實例依然還保有全部的功能。
- onUnmounted() : 注冊一個回調函數,在組件實例被卸載之后調用。
以下情況被視為已卸載
- 其所有子組件都已經被卸載。
- 所有相關的響應式作用 (渲染作用以及 setup() 時創建的計算屬性和偵聽器) 都已經停止。
可以在這個鉤子中手動清理一些副作用,例如計時器、DOM 事件監聽器或者與服務器的連接。
- KeepAlives緩存生命周期: 當組件實例從 DOM 上移除但因為被
<KeepAlive>
緩存而仍作為組件樹的一部分時,它將變為不活躍狀態而不是被卸載。當組件實例作為緩存樹的一部分插入到 DOM 中時,它將重新被激活。- onActivated() : 注冊一個回調函數,若組件實例是
<KeepAlive>
緩存樹的一部分,當組件被插入到 DOM 中時調用。 - onDeactivated() : 注冊一個回調函數,若組件實例是
<KeepAlive>
緩存樹的一部分,當組件從 DOM 中被移除時調用。
注:onActivated 在組件掛載時也會調用,并且 onDeactivated 在組件卸載時也會調用。
onActivated 和 onDeactivated 鉤子不僅適用于<KeepAlive>
緩存的根組件,也適用于緩存樹中的后代組件。 - onActivated() : 注冊一個回調函數,若組件實例是
- 捕獲組件錯誤:
- onErrorCaptured(): 注冊一個鉤子,在捕獲了后代組件傳遞的錯誤時調用。
捕獲錯誤來源:
- 組件渲染
- 事件處理器
- 生命周期鉤子
- setup() 函數
- 偵聽器
- 自定義指令鉤子
- 過渡鉤子
鉤子帶有三個實參:錯誤對象、觸發該錯誤的組件實例,以及一個說明錯誤來源類型的信息字符串。
可以在 errorCaptured() 中更改組件狀態來為用戶顯示一個錯誤狀態。
注意不要讓錯誤狀態再次渲染導致本次錯誤的內容,否則組件會陷入無限循環。
errorCaptured() 鉤子可以通過返回 false 來阻止錯誤繼續向上傳遞。
- onErrorCaptured(): 注冊一個鉤子,在捕獲了后代組件傳遞的錯誤時調用。
- 調試鉤子函數:
- onRenderTracked:每次渲染后重新收集響應式依賴
注冊一個調試鉤子,當組件渲染過程中追蹤到響應式依賴時調用。
鉤子僅在開發模式下可用,且在服務器端渲染期間不會被調用。 - onRenderTriggered:每次觸發頁面重新渲染時自動執行
注冊一個調試鉤子,當響應式依賴的變更觸發了組件渲染時調用。
鉤子僅在開發模式下可用,且在服務器端渲染期間不會被調用。
- onRenderTracked:每次渲染后重新收集響應式依賴
- onServerPrefetch(): 注冊一個異步函數,在組件實例在服務器上被渲染之前調用。
如果這個鉤子返回了一個 Promise,服務端渲染會在渲染該組件前等待該 Promise 完成。
這個鉤子僅會在服務端渲染中執行,可以用于執行一些僅存在于服務端的數據抓取過程。<script setup> import { ref, onServerPrefetch, onMounted } from 'vue' const data = ref(null) onServerPrefetch(async () => {// 組件作為初始請求的一部分被渲染// 在服務器上預抓取數據,因為它比在客戶端上更快。data.value = await fetchOnServer(/* ... */) })onMounted(async () => {if (!data.value) {// 如果數據在掛載時為空值,這意味著該組件// 是在客戶端動態渲染的。將轉而執行// 另一個客戶端側的抓取請求data.value = await fetchOnClient(/* ... */)} }) </script>
3.代碼示例
<script>
import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted,ref
} from 'vue'export default {setup () {// 其他的生命周期onBeforeMount (() => {console.log("App ===> 相當于 vue2.x 中 beforeMount")})onMounted (() => {console.log("App ===> 相當于 vue2.x 中 mounted")})// 注意,onBeforeUpdate 和 onUpdated 里面不要修改值onBeforeUpdate (() => {console.log("App ===> 相當于 vue2.x 中 beforeUpdate")})onUpdated (() => {console.log("App ===> 相當于 vue2.x 中 updated")})onBeforeUnmount (() => {console.log("App ===> 相當于 vue2.x 中 beforeDestroy")})onUnmounted (() => {console.log("App ===> 相當于 vue2.x 中 destroyed")})return {}}
}
</script>
父子組件中生命周期執行順序
1、只有父組件時,頁面組件一旦加載,生命周期及執行順序
beforeCreate(創建前)
created(創建后)
beforeMount(載入前)
mounted(載入后)
2、存在父子組件時,頁面組件一旦加載,生命周期及執行順序
父組件:beforeCreate、created、beforeMount
子組件:beforeCreate、created、beforeMount、mounted
父組件:mounted
v.3和v2.0生命周期對比
v2.0生命周期 | v.3生命周期 |
---|---|
beforeCreate (組件創建之前) | setup(組件創建之前) |
created(組件創建完成) | setup(組件創建完成) |
beforeMount (組件掛載之前) | onBeforeMount(組件掛載之前) |
mounted(組件掛載完成) | onMounted(組件掛載完成) |
beforeUpdate(數據更新,虛擬dom打補丁之前) | onBeforeUpdate(數據更新,虛擬dom打補丁之前) |
updated(數據更新,虛擬dom渲染完成) | onUpdated(數據更新,虛擬dom渲染完成) |
beforeDestroy(組件銷毀之前) | onBeforeUnmount(組件銷毀之前) |
destoryed(組件銷毀之后) | onUnmount(組件銷毀之后) |
- v2.0 注意
所有生命周期鉤子的 this 上下文將自動綁定至實例中,因此你可以訪問 data、computed 和 methods。這意味著你不應該使用箭頭函數來定義一個生命周期方法 (例如 created: () => this.fetchTodos())
因為箭頭函數綁定了父級上下文,所以 this 不會指向預期的組件實例,并且this.fetchTodos 將會是 undefined。