vue3生命周期函數
生命周期鉤子名稱對比表
階段 | Vue 2 選項式 API | Vue 3 組合式 API | 說明 |
---|---|---|---|
創建前 | beforeCreate | onBeforeCreate (已廢棄) | Vue 3 中?setup() ?替代 |
創建完成 | created | setup() (替代) | setup ?是入口,代替?beforeCreate ?和?created |
掛載前 | beforeMount | onBeforeMount() | 名稱一致 |
掛載完成 | mounted | onMounted() | 名稱一致 |
更新前 | beforeUpdate | onBeforeUpdate() | 名稱一致 |
更新完成 | updated | onUpdated() | 名稱一致 |
卸載前 | beforeDestroy | onBeforeUnmount() | 名稱變更! |
卸載完成 | destroyed | onUnmounted() | 名稱變更! |
錯誤捕獲 | errorCaptured | onErrorCaptured() | 名稱一致 |
激活(keep-alive) | activated | onActivated() | 名稱一致 |
停用(keep-alive) | deactivated | onDeactivated() | 名稱一致 |
調試:依賴追蹤 | 無 | onRenderTracked() | Vue 3 新增,開發模式專用 |
調試:觸發更新 | 無 | onRenderTriggered() | Vue 3 新增,開發模式專用 |
?? 重要:Vue 3 中 沒有
beforeDestroy
和destroyed
,它們被重命名為onBeforeUnmount
和onUnmounted
。
?詳細對比與示例
1???beforeCreate
?&?created
?→ 被?setup()
?替代
Vue 2 寫法:
export default {beforeCreate() {console.log('組件創建前');},created() {console.log('組件創建完成');this.fetchData();},methods: {fetchData() { /* ... */ }}
}
Vue 3 寫法(<script setup>
):
<script setup>
import { onMounted } from 'vue';// setup() 函數體直接執行,替代 beforeCreate 和 created
console.log('組件創建完成');function fetchData() { /* ... */ }onMounted(() => {fetchData();
});
</script>
? 說明:Vue 3 的
setup()
在組件實例創建后、onBeforeMount
之前執行,等價于 Vue 2 的beforeCreate
+created
。
2???beforeMount
?/?mounted
?→?onBeforeMount
?/?onMounted
Vue 2:
export default {mounted() {console.log('DOM 已掛載');this.$refs.input.focus();}
}
Vue 3:
<script setup>
import { onMounted, ref } from 'vue';const input = ref(null);onMounted(() => {console.log('DOM 已掛載');input.value.focus();
});
</script>
? 名稱一致,行為一致。
3???beforeUpdate
?/?updated
?→?onBeforeUpdate
?/?onUpdated
Vue 2:
export default {updated() {console.log('組件已更新');}
}
Vue 3:
<script setup>
import { onUpdated } from 'vue';onUpdated(() => {console.log('組件已更新');
});
</script>
? 完全一致。
4???beforeDestroy
?/?destroyed
?→?onBeforeUnmount
?/?onUnmounted
(?? 名稱變更)
Vue 2:
export default {beforeDestroy() {this.timer && clearInterval(this.timer);window.removeEventListener('resize', this.handleResize);},destroyed() {console.log('組件已銷毀');}
}
Vue 3:
<script setup>
import { onMounted, onBeforeUnmount } from 'vue';let timer = null;onMounted(() => {timer = setInterval(() => { /* ... */ }, 1000);window.addEventListener('resize', handleResize);
});// ? 注意:是 onBeforeUnmount,不是 beforeDestroy
onBeforeUnmount(() => {if (timer) clearInterval(timer);window.removeEventListener('resize', handleResize);console.log('組件即將卸載');
});// onUnmounted 也可用
onUnmounted(() => {console.log('組件已卸載');
});
</script>
🔴 重點:
beforeDestroy
→onBeforeUnmount
,destroyed
→onUnmounted
這是 唯一命名不一致 的地方,遷移時務必注意!
5???activated
?/?deactivated
?→?onActivated
?/?onDeactivated
Vue 2:
export default {activated() {console.log('組件被激活');},deactivated() {console.log('組件被緩存');}
}
Vue 3:
<script setup>
import { onActivated, onDeactivated } from 'vue';onActivated(() => {console.log('組件被激活');
});onDeactivated(() => {console.log('組件被緩存');
});
</script>
? 名稱一致,行為一致。
6?? Vue 3 新增調試鉤子
import { onRenderTracked, onRenderTriggered } from 'vue';onRenderTracked((event) => {console.log('依賴被追蹤:', event);
});onRenderTriggered((event) => {console.log('更新被觸發:', event);
});
💡 僅在開發模式有效,用于調試響應式系統,Vue 2 無對應功能。
🔄 生命周期執行順序(Vue 2 vs Vue 3 完全一致)
setup() ← 替代 beforeCreate + created↓
onBeforeMount() ← beforeMount↓
onMounted() ← mounted↓
onBeforeUpdate() ← beforeUpdate↓
onUpdated() ← updated↓
onBeforeUnmount() ← beforeDestroy↓
onUnmounted() ← destroyed
? 執行順序完全相同,只是寫法和部分名稱變化。
?生命周期執行順序示例
import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted
} from 'vue';export default {setup() {console.log('1. setup');onBeforeMount(() => {console.log('2. onBeforeMount');});onMounted(() => {console.log('3. onMounted');});onBeforeUpdate(() => {console.log('4. onBeforeUpdate');});onUpdated(() => {console.log('5. onUpdated');});onBeforeUnmount(() => {console.log('6. onBeforeUnmount');});onUnmounted(() => {console.log('7. onUnmounted');});return {};}
};
? Vue 3 的優勢(組合式 API)
優勢 | 說明 |
---|---|
邏輯復用更強 | 可在任意?.js ?文件中使用生命周期鉤子,封裝可復用邏輯(如?useMouse.js ) |
更好的 TypeScript 支持 | 類型推導更準確 |
減少?this ?混亂 | 不再依賴?this ,避免箭頭函數中?this ?指向問題 |
按邏輯組織代碼 | 不再分散在?data 、methods 、watch ?中,而是按功能組織 |
🚀 遷移建議
beforeDestroy
?→?onBeforeUnmount
destroyed
?→?onUnmounted
created
?邏輯移到?setup()
?中- 所有生命周期鉤子前加?
on
?前綴并從?vue
?導入 - 優先使用?
<script setup>
?+ 組合式 API
? 總結
對比項 | Vue 2 | Vue 3 |
---|---|---|
核心變化 | 選項式 API | 組合式 API(推薦) |
生命周期名稱 | beforeDestroy ,?destroyed | onBeforeUnmount ,?onUnmounted |
入口函數 | created | setup() |
寫法 | 選項對象 | 導入函數 |
邏輯復用 | mixins(有缺陷) | 自定義 Hook(推薦) |
調試能力 | 一般 | 增強(onRenderTracked ?等) |
💡 一句話總結:
Vue 3 的生命周期“行為不變、順序不變”,只是“寫法更新、命名微調、能力增強”。
掌握onBeforeUnmount
和onUnmounted
的命名變化,就能輕松遷移!
以前的選項api還可以用嗎
選項式 API 在 Vue 3 中依然有效
你完全可以像 Vue 2 那樣寫代碼:
<!-- Vue 3 中完全支持的選項式 API -->
<script>
export default {name: 'MyComponent',// ? datadata() {return {count: 0,message: 'Hello Vue 3'}},// ? 生命周期鉤子(注意:名稱已更新)created() {console.log('組件創建完成');},mounted() {console.log('組件已掛載');},// ?? 注意:Vue 3 中是 beforeUnmount 和 unmountedbeforeUnmount() {console.log('組件即將卸載');},unmounted() {console.log('組件已卸載');},// ? methodsmethods: {increment() {this.count++;}},// ? computedcomputed: {doubleCount() {return this.count * 2;}},// ? watchwatch: {count(newVal, oldVal) {console.log(`count 從 ${oldVal} 變為 ${newVal}`);}}
}
</script><template><div><p>{{ message }}</p><p>Count: {{ count }}</p><p>Double: {{ doubleCount }}</p><button @click="increment">+1</button></div>
</template>
? 這段代碼在 Vue 3 中可以直接運行,無需修改。
2?? 與 Vue 2 的主要區別(僅兩處)
功能 | Vue 2 | Vue 3(選項式 API) |
---|---|---|
銷毀前鉤子 | beforeDestroy | beforeUnmount |
銷毀完成鉤子 | destroyed | unmounted |
🔴 重要:這是唯一不兼容的地方。
如果你從 Vue 2 遷移,需要將:
beforeDestroy
?→ 改為?beforeUnmount
destroyed
?→ 改為?unmounted
3?? Vue 3 推薦使用?<script setup>
(組合式 API)
雖然選項式 API 可用,但 Vue 3 官方更推薦使用 <script setup>
,因為它:
- 更好的邏輯復用(自定義 Hook)
- 更強的 TypeScript 支持
- 更靈活的代碼組織(按功能而非選項分組)
- 更接近 React Hooks 的開發體驗
<script setup>
import { ref, computed, watch, onMounted } from 'vue';const count = ref(0);
const message = ref('Hello Vue 3');const doubleCount = computed(() => count.value * 2);watch(count, (newVal) => {console.log('count 變化:', newVal);
});onMounted(() => {console.log('組件已掛載');
});function increment() {count.value++;
}
</script><template><div><p>{{ message }}</p><p>Count: {{ count }}</p><p>Double: {{ doubleCount }}</p><button @click="increment">+1</button></div>
</template>
4?? 你可以在同一個項目中混合使用
Vue 3 允許你:
- 新組件用?
<script setup>
(組合式 API) - 老組件保留選項式 API
- 甚至在一個組件中混合使用(不推薦)
<script setup>
import { ref } from 'vue';const setupCount = ref(0);
</script><script>
export default {data() {return {optionsCount: 0}},methods: {incrementOptions() {this.optionsCount++;}}
}
</script>
? 這是合法的,但不建議混合使用,會造成代碼混亂。
5?? 官方態度
- Vue 團隊明確表示:選項式 API 不會廢棄
- 它仍然是 Vue 3 的一等公民
- 適合:
- 簡單組件
- 初學者
- 從 Vue 2 遷移的項目
? 總結
問題 | 回答 |
---|---|
Vue 2 的選項式 API 在 Vue 3 中還能用嗎? | ??能用!完全支持 |
是否需要修改? | ?? 只需將?
|
是否推薦使用? | 👍 適合簡單場景、遷移項目、初學者 但官方更推薦? |
會不會被廢棄? | ??不會,Vue 團隊承諾長期支持 |
💡 建議:
- 新項目:優先學習和使用?
<script setup>
(組合式 API)- 老項目遷移:可以先保留選項式 API,逐步重構
- 團隊協作:統一風格,避免混合使用
所以,放心使用!Vue 3 對選項式 API 的支持非常友好,你有充分的時間去學習和過渡到組合式 API。