EP11 - 生命週期鉤子

更新於 發佈於 閱讀時間約 1 分鐘
Lifecycle Hooks,感覺蠻有趣~生命週期有哪些狀態?
照理說應該會看到一個流程圖的樣子~
對於生命週期都會覺得比較常用通常是某幾個階段~
我只想要Destroy這個生命週期~www

每個 Vue 組件實例在創建時會經歷一系列的初始化步驟例。例如,它需要設置數據觀測編譯模板將實例掛載到 DOM 上,並在數據變更時更新 DOM。在這些過程中,它會執行稱為生命週期鉤子函數,這些鉤子允許用戶在特定階段插入自己的代碼。

註冊生命週期鉤子 - Registering Lifecycle Hooks

例如,onMounted 鉤子可以在組件完成初始渲染並創建 DOM 節點後運行代碼:

<script setup>
import { onMounted } from 'vue'

onMounted(() => {
console.log(`組件現在已經掛載。`)
})
</script>

還有其他鉤子會在實例的不同生命週期階段被調用,其中最常用的是 onMountedonUpdatedonUnmounted

調用 onMounted 時,Vue 會自動將註冊的回調函數與當前活躍的組件實例關聯起來。這要求這些鉤子必須在組件設置期間同步註冊。例如,不要這樣做:

setTimeout(() => {
onMounted(() => {
// 這樣做不會奏效。
})
}, 100)

注意,這並不意味著調用必須放置在 setup()<script setup> 內部。onMounted() 可以在外部函數中調用,只要調用堆棧是同步的,並且源自 setup() 內部即可。

Q:為什麼不會奏效?

在 Vue 中,onMounted 鉤子需要在組件的設置階段同步註冊。這是因為 Vue 需要在組件實例的生命週期內部確保所有的鉤子都已正確註冊。如果你在非同步操作中(例如 setTimeout)調用 onMounted,這樣的註冊可能會在組件的生命週期階段之外進行,因此不會如預期地工作。

  1. setTimeout 是一個非同步操作,它會在指定的時間(這裡是 100 毫秒)後執行其回調函數。
  2. onMounted 鉤子的註冊會被延遲到 setTimeout 的回調中。由於 setTimeout 是非同步的,這可能會在 Vue 的組件實例已經完成設置之後執行,這時組件的生命週期已經不再適合進行這些鉤子的註冊。
  3. 因此,onMounted 的回調函數可能無法正確地與組件實例關聯,從而導致該鉤子不會如預期執行。
要確保 onMounted 鉤子能正常工作,它應該在組件的設置過程中同步註冊,而不是在非同步操作中。這樣 Vue 可以在適當時間點觸發這些鉤子,保證能正確地執行。

Vue 組件實例的生命周期圖 - Lifecycle Diagram​

下圖展示了 Vue 組件實例的生命周期。在你剛開始學習時,可能不需要完全理解其中的每個細節,但隨著你學習和構建更多的項目,它將成為一個有用的參考工具。

raw-image

常見的生命周期鉤子

  • onBeforeMount: 當組件即將被掛載到 DOM 上時調用。此時,虛擬 DOM 已經渲染完畢,但真實的 DOM 還沒有更新。
  • onMounted: 組件已經掛載到 DOM 上時調用。此時,DOM 已經可用,可以進行 DOM 操作。
  • onBeforeUpdate: 當組件的響應式數據發生變化並即將更新 DOM 之前調用。可以在這裡查看更新前的狀態。
  • onUpdated: 組件的 DOM 更新完成後調用。此時可以獲取到最新的 DOM 狀態。
  • onBeforeUnmount: 組件即將從 DOM 上移除時調用。可以在這裡進行一些清理工作。
  • onUnmounted: 組件已經從 DOM 上移除後調用。此時組件的所有響應式數據、監聽器等都已經被銷毀。

其他生命周期鉤子

除了上面提到的常見鉤子外,還有一些其他鉤子在特定場景下非常有用:

  • onActivated: 當組件從 <keep-alive> 緩存中激活時調用。
  • onDeactivated: 當組件被 <keep-alive> 緩存時調用。
  • onErrorCaptured: 當捕獲到組件內部的錯誤時調用,用於錯誤邊界處理。
<template>
<div>
<p>Component Lifecycle Hooks Example</p>
</div>
</template>

<script setup>
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onActivated, onDeactivated, onErrorCaptured } from 'vue'

onBeforeMount(() => {
console.log('beforeMount - 組件即將掛載')
})

onMounted(() => {
console.log('mounted - 組件已掛載')
})

onBeforeUpdate(() => {
console.log('beforeUpdate - 組件即將更新')
})

onUpdated(() => {
console.log('updated - 組件已更新')
})

onBeforeUnmount(() => {
console.log('beforeUnmount - 組件即將銷毀')
})

onUnmounted(() => {
console.log('unmounted - 組件已銷毀')
})

onActivated(() => {
console.log('activated - 組件已激活')
})

onDeactivated(() => {
console.log('deactivated - 組件已停用')
})

onErrorCaptured((err, instance, info) => {
console.error('errorCaptured - 捕獲到錯誤:', err, info)
})
</script>
beforeMount - 組件即將掛載
mounted - 組件已掛載
beforeUpdate - 組件即將更新
updated - 組件已更新
activated - 組件已激活
deactivated - 組件已停用
beforeUnmount - 組件即將銷毀
unmounted - 組件已銷毀
errorCaptured - 捕獲到錯誤: ...

請注意,如果你的組件沒有使用 <keep-alive>,則 activateddeactivated 鉤子不會觸發。如果你的組件或其子組件沒有拋出錯誤,則 errorCaptured 鉤子也不會觸發。

若要了解所有生命周期鉤子及其相應的使用案例,請查閱 Vue 的生命周期鉤子 API 參考文件。這些鉤子允許你在 Vue 組件實例的不同階段執行自定義代碼,使你能夠更靈活地控制組件的行為。

Q:什麼是<keep-alive>?

<keep-alive> 是 Vue 提供的一個內建組件,用於包裹動態組件,從而在其激活和停用之間保留組件的狀態或避免重新渲染。這在需要在不同視圖之間切換時非常有用,例如導航標籤或多頁應用。

生命週期鉤子的作用

  1. activated 鉤子
    • 當組件被 <keep-alive> 包裹且激活時(即重新顯示)會觸發。
    • 可以在這裡執行一些初始化工作或重新設置一些狀態。
  2. deactivated 鉤子
    • 當組件被 <keep-alive> 包裹且停用時(即隱藏)會觸發。
    • 可以在這裡保存狀態或執行一些清理工作。

使用示例

假設有一個包含兩個子組件的 Vue 應用,每個子組件會在不同的選項卡中顯示。我們使用 <keep-alive> 來包裹這些子組件,這樣在切換選項卡時不會重新創建和銷毀組件,而是保留其狀態。

<template>
<div>
<button @click="currentView = 'view1'">View 1</button>
<button @click="currentView = 'view2'">View 2</button>

<keep-alive>
<component :is="currentView"></component>
</keep-alive>
</div>
</template>

<script setup>
import { ref } from 'vue'
import View1 from './View1.vue'
import View2 from './View2.vue'

const currentView = ref('view1')
</script>

有兩個按鈕,分別用來切換當前顯示的視圖。

  1. @click="currentView = 'view1'":點擊這個按鈕會將 currentView 設置為 'view1'
  2. @click="currentView = 'view2'":點擊這個按鈕會將 currentView 設置為 'view2'
  3. <keep-alive> 是一個 Vue 的內建組件,用來包裹動態組件。它會在組件激活和停用之間保持其狀態,不會每次都重新創建和銷毀組件。
  4. <component :is="currentView"></component><component> 是一個動態組件,可以根據 currentView 的值來渲染不同的組件。currentView 的值決定了哪個組件會被渲染。
  5. :is 是一個綁定屬性,用來指定要渲染的組件名稱。這個屬性可以接受一個字符串或一個組件對象。

子組件View1.vue中的 activateddeactivated

<template>
<div>
<p>This is View 1</p>
</div>
</template>

<script setup>
import { onActivated, onDeactivated } from 'vue'

onActivated(() => {
console.log('View 1 is activated')
})

onDeactivated(() => {
console.log('View 1 is deactivated')
})
</script>

類似的子組件 View2.vue

<template>
<div>
<p>This is View 2</p>
</div>
</template>

<script setup>
import { onActivated, onDeactivated } from 'vue'

onActivated(() => {
console.log('View 2 is activated')
})

onDeactivated(() => {
console.log('View 2 is deactivated')
})
</script>

運行結果

當你在選項卡之間切換時,你會在控制台看到類似以下的輸出:

View 1 is activated
View 1 is deactivated
View 2 is activated
View 2 is deactivated
生命週期這玩意常常搞得我一個頭兩個大~
每個鉤子放log,看看每個週期的先後順序跟邏輯
然後就是觀察自動同步的時候是哪個週期?

Q:自動同步在哪個週期?

<template>
<div>
<p>Component Lifecycle Hooks Logging Example</p>
<button @click="updateMessage">Update Message</button>
<p>{{ message }}</p>
</div>
</template>

<script setup>
import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue'

const message = ref('Hello, Vue!')

// 生命週期鉤子放置 log
onBeforeMount(() => {
console.log('beforeMount - 組件即將掛載')
})

onMounted(() => {
console.log('mounted - 組件已掛載')
})

onBeforeUpdate(() => {
console.log('beforeUpdate - 組件即將更新')
})

onUpdated(() => {
console.log('updated - 組件已更新')
})

onBeforeUnmount(() => {
console.log('beforeUnmount - 組件即將銷毀')
})

onUnmounted(() => {
console.log('unmounted - 組件已銷毀')
})

// 更新消息的方法
const updateMessage = () => {
message.value = 'Message updated!'
}
</script>

在上述示例中,當點擊按鈕更新消息時,可以看到 beforeUpdateupdated 鉤子的觸發順序。這表明在數據變化後,Vue 開始自動同步 DOM,在此期間 beforeUpdate 鉤子被觸發,DOM 更新完成後 updated 鉤子被觸發。

留言
avatar-img
留言分享你的想法!
avatar-img
卡關的人生
2會員
73內容數
分享生活趣事~
卡關的人生的其他內容
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
看更多
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
前言 從零開始構建一個 DateTimePicker 可能看起來令人畏懼,但試想一下你將獲得的靈活性和控制力。在這個系列中,我們將逐步揭開構建過程的神秘面紗,讓您能夠創建一個完全符合需求的自定義 DateTimePicker。 本文章,屬於付費系列的文章,這篇文章,我會希望讀者可以得到的
Thumbnail
前言 從零開始構建一個 DateTimePicker 可能看起來令人畏懼,但試想一下你將獲得的靈活性和控制力。在這個系列中,我們將逐步揭開構建過程的神秘面紗,讓您能夠創建一個完全符合需求的自定義 DateTimePicker。 本文章,屬於付費系列的文章,這篇文章,我會希望讀者可以得到的
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
Vue Router 動態路由,假設有一個賣場,裡面有 100 個商品,我們不可能針對它們創 100 對應的路由,因此我們需要一個動態路由,利用"路徑帶參數"的方式來撈取商品的資訊。
Thumbnail
Vue Router 動態路由,假設有一個賣場,裡面有 100 個商品,我們不可能針對它們創 100 對應的路由,因此我們需要一個動態路由,利用"路徑帶參數"的方式來撈取商品的資訊。
Thumbnail
這系列是我在 2023 六角學院 Vue作品實戰班的筆記,筆記以本人理解的方式記錄。此篇主題為 Slot Props 進階應用 ,其中包含單筆資料、多筆資料。
Thumbnail
這系列是我在 2023 六角學院 Vue作品實戰班的筆記,筆記以本人理解的方式記錄。此篇主題為 Slot Props 進階應用 ,其中包含單筆資料、多筆資料。
Thumbnail
前言 Vue 是一個現代開發框架,擁有完尚的生態系,讓我們可以將須多元件客製化,做出組件,並且可重複利用,高擴充性。在開發組件時,每個組件都擁有自己的生命周期,Vue 組件會偵測每個變數值,是否有變,並且更新內容,今天要一個一個了解 Vue 的生命週期,讓大家有更多認識。 Vue 的生命週期
Thumbnail
前言 Vue 是一個現代開發框架,擁有完尚的生態系,讓我們可以將須多元件客製化,做出組件,並且可重複利用,高擴充性。在開發組件時,每個組件都擁有自己的生命周期,Vue 組件會偵測每個變數值,是否有變,並且更新內容,今天要一個一個了解 Vue 的生命週期,讓大家有更多認識。 Vue 的生命週期
Thumbnail
今天來介紹 vue 的生命週期,什麼是生命週期呢?講簡單一點就是從你用瀏覽器打開網頁開始,到網頁內的元件一個一個生成,到整個完整的網頁建立的過程就叫生命週期,完整過程如下圖 是不是眼花撩亂啊?讓我簡化一下,其實主要順序就是如下圖 在加上 setup 語法糖的 script 標籤內做的事相當於在 be
Thumbnail
今天來介紹 vue 的生命週期,什麼是生命週期呢?講簡單一點就是從你用瀏覽器打開網頁開始,到網頁內的元件一個一個生成,到整個完整的網頁建立的過程就叫生命週期,完整過程如下圖 是不是眼花撩亂啊?讓我簡化一下,其實主要順序就是如下圖 在加上 setup 語法糖的 script 標籤內做的事相當於在 be
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News