Vue 3 引入了 Composition API,使得生命周期鉤子(hooks)在函數式風格中更清晰地表達。本篇文章將從官方 hooks 的使用、實現原理以及自定義 hooks 的結構化思路出發,全面理解 Vue 3 的 hooks 系統。
📘 1. Vue 3 官方生命周期 hooks 一覽
Hook 函數 | 觸發時機 |
---|---|
onBeforeMount | 組件掛載前 |
onMounted | 組件掛載后 |
onBeforeUpdate | 數據變更、視圖更新前 |
onUpdated | 數據變更、視圖更新后 |
onBeforeUnmount | 卸載前 |
onUnmounted | 卸載后 |
onActivated | <KeepAlive> 激活時 |
onDeactivated | <KeepAlive> 失活時 |
onErrorCaptured | 錯誤捕獲 |
onRenderTracked | 響應式依賴追蹤 |
onRenderTriggered | 響應式依賴觸發更新 |
? 2. 使用示例
<script setup>
import { onMounted } from 'vue'onMounted(() => {console.log('組件已掛載完成')
})
</script>
在
<script setup>
中調用 hooks 更簡潔,無需訪問setup()
返回對象。
🧠 3. 實現原理解析
生命周期 hooks 的注冊基于當前組件實例 currentInstance
:
export function onMounted(hook: Function, target = currentInstance) {return injectHook('mounted', hook, target)
}
核心函數 injectHook
:
function injectHook(type: LifecycleHooks, hook: Function, target) {const hooks = target[type] || (target[type] = [])hooks.push(hook)
}
當組件進入對應生命周期階段時,Vue 內部會遍歷執行掛載在實例上的所有該類型 hook。
?? 4. 自定義 Hooks(組合邏輯復用)
Vue 3 鼓勵將邏輯拆分為 useXxx
函數,以便跨組件復用。
🎯 示例:useWindowSize
// useWindowSize.ts
import { ref, onMounted, onUnmounted } from 'vue'export function useWindowSize() {const width = ref(window.innerWidth)const height = ref(window.innerHeight)const update = () => {width.value = window.innerWidthheight.value = window.innerHeight}onMounted(() => window.addEventListener('resize', update))onUnmounted(() => window.removeEventListener('resize', update))return { width, height }
}
使用方式:
<script setup>
import { useWindowSize } from '@/hooks/useWindowSize'const { width, height } = useWindowSize()
</script>
🧠 自定義 hooks 的原理
- 本質是普通函數,內部調用 Vue 組合式 API(如
ref
,watch
,onMounted
) - 在組件
setup()
時執行,響應式變量掛接到當前組件上下文 - 內部調用生命周期鉤子時會依賴當前的
getCurrentInstance()
📌 5. 總結對比
類型 | 示例 | 作用 | 特點 |
---|---|---|---|
官方生命周期 Hook | onMounted() | 注冊生命周期回調 | 由 Vue 內部調度 |
自定義 Hook | useMousePosition() | 封裝響應式狀態 + 邏輯復用 | 是普通函數,可組合嵌套 |
📚 推薦閱讀
- Vue 3 官方生命周期 API
- Vue 核心源碼 Lifecycle 實現
- VueUse - 高質量 Hooks 集合
?? 結語
生命周期 hooks 是 Vue 3 中非常核心的機制之一。理解它們的用法與實現,有助于我們編寫結構清晰、邏輯可復用的組件。
如果你對 Vue 源碼感興趣,不妨進一步探索 Vue 是如何依賴 currentInstance
來處理作用域鉤子的注冊和調用的。