图片取自vue3官网教程:cn.vuejs.org/guide/essen…
一个关键点是: <script setup> 本身就是在 beforeCreate 和 created 阶段执行的。
因此,在 <script setup> 中,没有 beforeCreate 和 created 这两个钩子。在<script> 标签顶层编写的任何代码(比如定义变量、console.log)都可以看作是在 created 钩子中执行的。
组合式api中主要的6个生命周期钩子
以下是 <script setup> 中常用的生命周期钩子函数,按执行顺序列出:
-
onBeforeMount- 时机: 在组件即将被挂载到 DOM 之前调用。此时,
template已经编译完成,但尚未渲染成真实的 DOM。
- 时机: 在组件即将被挂载到 DOM 之前调用。此时,
-
onMounted- 时机: 在组件被挂载到 DOM 之后调用。此时,组件已经渲染完毕,你可以访问到真实的 DOM 元素。
-
onBeforeUpdate- 时机: 当组件的响应式数据(如
ref或reactive)发生变化,即将触发 DOM 更新之前调用。
- 时机: 当组件的响应式数据(如
-
onUpdated- 时机: 在组件的 DOM 更新完成之后调用。
-
onBeforeUnmount- 时机: 在组件实例即将被卸载和销毁之前调用。此时组件功能仍然正常。
-
onUnmounted- 时机: 在组件实例被卸载和销毁之后调用。
举个栗子
为了看到更新相关的钩子 (
onBeforeUpdate,onUpdated),添加了一个按钮来改变一个响应式数据。卸载相关的钩子 (onBeforeUnmount,onUnmounted),需要在父组件中通过v-if来控制这个LifecycleDemo组件的显示和隐藏。
<template>
<div class="lifecycle-demo">
<h3>Vue 3 <script setup> 生命周期演示</h3>
<p>
当前计数值 (count): <strong>{{ count }}</strong>
</p>
<button @click="increment">增加 count</button>
<p><i>打开浏览器的控制台查看生命周期日志。</i></p>
</div>
</template>
<script setup lang="ts">
// 1. 导入所有需要的 API
import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue';
// --- "created" 阶段 ---
// ( <script setup> 顶层的代码会在 "created" 之前执行)
console.log('--- 1. script setup ---');
console.log('组件正在被创建 (类似 "created")');
// 定义响应式数据
const count = ref(0);
const increment = () => {
count.value++;
};
// --- 挂载阶段 ---
onBeforeMount(() => {
console.log('--- 2. onBeforeMount ---');
console.log('组件即将挂载,DOM 尚未创建。');
console.log('count 值:', count.value);
});
onMounted(() => {
console.log('--- 3. onMounted ---');
console.log('组件已挂载,DOM 已创建。');
// 此时可以安全地访问 DOM,例如:
// const el = document.querySelector('.lifecycle-demo');
// console.log('DOM 元素:', el);
});
// --- 更新阶段 ---
// (点击 "增加 count" 按钮时触发)
onBeforeUpdate(() => {
console.log('--- 4. onBeforeUpdate ---');
console.log('数据已更新,但 DOM 尚未更新。');
console.log('即将更新的 count 值:', count.value);
});
onUpdated(() => {
console.log('--- 5. onUpdated ---');
console.log('DOM 已更新。');
console.log('更新后的 count 值:', count.value);
});
// --- 卸载阶段 ---
// (当这个组件从父组件中被 v-if="false" 移除时触发)
onBeforeUnmount(() => {
console.log('--- 6. onBeforeUnmount ---');
console.log('组件即将卸载。');
// 适合在此处清理定时器、事件监听器等
// clearInterval(myTimer);
});
onUnmounted(() => {
console.log('--- 7. onUnmounted ---');
console.log('组件已卸载。');
});
</script>
<style scoped>
.lifecycle-demo {
padding: 20px;
border: 2px solid #42b983;
border-radius: 8px;
background-color: #f0f9f5;
}
button {
margin-top: 10px;
padding: 8px 12px;
background-color: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #36a476;
}
</style>
控制台输出顺序
- 组件挂载
- 点击按钮修改数据
- 在父组件中控制组件切换