每个Vue组件都会经历从创建到销毁的完整生命周期。在这个过程中,Vue会在特定的时机调用一些函数,这些函数就是生命周期钩子。通过生命周期钩子,我们可以在组件的不同阶段执行操作,比如初始化数据、发送请求、清理资源等。
理解生命周期对于开发Vue应用非常重要。它帮助我们理解组件的工作机制,知道在什么时候可以访问DOM,什么时候可以发送请求,什么时候需要清理资源。在这一堂课中,我们将深入学习Vue的生命周期。

Vue组件的生命周期可以分为几个阶段:创建、挂载、更新和销毁。每个阶段都有对应的钩子函数,我们可以在这些钩子中执行特定的操作。
让我们通过一个简单的例子来理解生命周期:
<div id="app">
<lifecycle-demo :count="count"></lifecycle-demo>
<button @click="count++">增加计数</button>
</div>
<script>
const { createApp, ref } = Vue;
const LifecycleDemo = {
props: ['count'],
beforeCreate() {
console.log('beforeCreate: 组件实例刚被创建,数据和方法还未初始化');
},
created() {
console.log('created: 组件实例创建完成,数据和方法已初始化,但还未挂载到DOM');
},
beforeMount() {
console.log('beforeMount: 组件挂载到DOM之前');
},
mounted() {
console.log('mounted: 组件已挂载到DOM,可以访问DOM元素');
},
beforeUpdate() {
console.log('beforeUpdate: 组件更新之前');
},
updated() {
console.log('updated: 组件更新完成');
},
beforeUnmount() {
console.log('beforeUnmount: 组件卸载之前');
},
unmounted() {
console.log('unmounted: 组件已卸载');
},
template: `
<div>
<p>计数:{{ count }}</p>
</div>
`
};
const app = createApp({
setup() {
const count = ref(0);
return {
count
};
},
components: {
'lifecycle-demo': LifecycleDemo
}
});
app.mount('#app');
</script>如果你运行这段代码并观察控制台,你会看到各个生命周期钩子的执行顺序。这帮助我们理解组件在不同阶段的状态。
在选项式API(Options API)中,我们可以通过在组件对象的选项中直接声明各类生命周期钩子函数(如 beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeUnmount、unmounted 等)。 这些钩子会在组件的不同生命周期阶段自动依次调用,允许我们在组件初始化、DOM 挂载、数据变更、卸载等关键时刻插入自定义逻辑。例如,你可以在 created 钩子里发起数据请求、在 mounted 钩子中操作 DOM、在 beforeUnmount 中做清理工作。 每个生命周期钩子都作为组件对象的一个方法选项直接存在,与 data、methods、computed 等属性并列。这样可以帮助我们精确掌控组件的整个生命周期过程。
<div id="app">
<component-a></component-a>
</div>
<script>
const { createApp } = Vue;
const ComponentA = {
data() {
return {
message: 'Hello Vue'
};
},
beforeCreate() {
:组件实例刚被创建,此时this还未创建,无法访问data、methods`等。这个钩子很少使用。:组件实例创建完成,此时可以访问data、methods`等,但DOM还未创建。这是发送请求、初始化数据的好时机。当组件的数据(如 data、props 等)发生变化时,Vue 会自动触发一组“更新阶段的生命周期钩子”。这些钩子的执行顺序如下:
通过这些钩子,你可以在数据变更、组件重新渲染的各个阶段进行相应的操作,比如:在 DOM 更新前执行某些计算逻辑,在 DOM 更新后与界面进行交互等。
<div id="app">
<counter-component></counter-component>
</div>
<script>
const { createApp } = Vue;
const CounterComponent = {
data() {
return {
count: 0
};
},
beforeUpdate() {
beforeUpdate:数据已更新,但DOM还未更新。这个钩子很少使用。updated:DOM已更新。可以在这里操作更新后的DOM,但要注意避免在这里修改数据,否则可能导致无限循环。当组件被销毁(卸载)时,会依次触发两个销毁阶段(卸载阶段)的生命周期钩子:beforeUnmount 和 unmounted。
beforeUnmount:组件实例将要被卸载时调用,在这个钩子中通常进行一些清理操作,比如清除定时器、移除事件监听等。此时组件仍然可以访问所有的数据和 DOM。unmounted:组件实例已经被卸载并销毁时调用,这时你已经无法访问组件实例中的数据和 DOM 节点,常用于一些最终的清理操作或者发送日志等。这些钩子主要用于组件销毁时的资源管理,避免内存泄漏或副作用残留。
<div id="app">
<button @click="show = !show">切换显示</button>
<component-b v-if="show"></component-b>
</div>
<script>
const { createApp, ref } = Vue;
const ComponentB = {
在组件销毁时,一定要清理资源,比如定时器、事件监听器等。否则可能导致内存泄漏。
在组合式 API 中,生命周期钩子不能像选项式 API 那样直接写作对象方法,而是需要单独从 Vue 中按需导入,然后在 setup 函数内调用对应的钩子函数。例如:
import { onMounted, onUnmounted } from 'vue';
setup() {
onMounted(() => {
// 组件挂载后执行的逻辑
});
onUnmounted(() => {
// 组件卸载时执行的逻辑
});
}常用的生命周期钩子包括 onBeforeMount、onMounted、onBeforeUpdate、onUpdated、onBeforeUnmount、onUnmounted 等,全部以“on”为前缀,便于区分。
<div id="app">
<component-c></component-c>
</div>
<script>
const { createApp, ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } = Vue;
const ComponentC =
在组合式API中,生命周期钩子的命名稍有不同:beforeCreate和created被setup替代,其他钩子都加上了on前缀。
注意,组合式API中没有beforeCreate和created钩子,因为setup函数在这些钩子之前执行。如果你需要在组件创建时执行操作,直接在setup中执行即可。
不同的生命周期钩子适用于不同的场景。让我们看一些实际的使用场景:
<div id="app">
<user-list></user-list>
</div>
<script>
const { createApp, ref } = Vue;
const UserList = {
data() {
return {
users: [],
loading: false
};
在这个例子中,我们在created钩子中发送请求获取用户列表。虽然也可以在mounted中发送请求,但在created中发送可以更早获取数据。
<div id="app">
<chart-component></chart-component>
</div>
<script>
const { createApp } = Vue;
const ChartComponent = {
mounted() {
// DOM已挂载,可以初始化图表库
const canvas = this.$el.querySelector('canvas'
在这个例子中,我们在mounted钩子中操作DOM,初始化图表。因为只有在mounted之后,DOM元素才真正存在。
<div id="app">
<button @click="show = !show">切换显示</button>
<timer-component v-if="show"></timer-component>
</div>
<script>
const { createApp, ref } = Vue;
const TimerComponent = {
在这个例子中,我们在beforeUnmount钩子中清理定时器。如果不清理,定时器会继续运行,导致内存泄漏。
让我们通过一个图示来理解完整的生命周期流程:
下面我们将通过一个更详细的综合示例,来全面巩固和理解 Vue 组件的生命周期。
在这个示例中,我们会自定义一个组件,并在每个生命周期钩子中进行不同的操作与日志记录,以观察生命周期的完整流程,以及每一步执行的时机和作用。
你可以通过切换、修改 props 等操作,直观地看到各生命周期钩子的调用顺序和效果。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期钩子示例</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
在这个例子中,我们创建了一个组件,它会在各个生命周期钩子中记录日志。通过观察日志,我们可以清楚地看到组件生命周期的执行顺序。
在这一部分中,我们学习了Vue的生命周期钩子。我们了解了组件从创建到销毁的完整生命周期,学习了选项式API和组合式API中的生命周期钩子,以及它们的使用场景。 理解生命周期对于开发Vue应用非常重要。它帮助我们理解组件的工作机制,知道在什么时候可以访问DOM,什么时候可以发送请求,什么时候需要清理资源。
在下一堂课,我们将学习组合式API,了解setup函数、组合式函数等高级特性。