一、生命周期概述

Vue3的生命周期是指组件从创建到销毁的整个过程,期间会触发一系列钩子函数,允许我们在特定阶段执行代码。理解生命周期有助于更好地控制组件行为。

Vue3提供了两种API风格的生命周期:

  • 选项式API(Options API):与Vue2类似的生命周期钩子
  • 组合式API(Composition API):通过导入函数使用的生命周期钩子

二、选项式API生命周期

2.1 完整生命周期示例

<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="updateMessage">更新消息</button>
  </div>
</template>

<script>
export default {
  // 1. 组件实例创建前
  beforeCreate() {
    console.log('beforeCreate: 组件实例创建前');
    // 此时data和methods尚未初始化,无法访问
  },
  
  // 2. 组件实例创建后
  created() {
    console.log('created: 组件实例创建后');
    // 此时data和methods已初始化,可以访问
    // 常用作数据初始化、API请求等
  },
  
  // 3. 组件挂载前
  beforeMount() {
    console.log('beforeMount: 组件挂载前');
    // 此时模板已编译,但尚未挂载到DOM
  },
  
  // 4. 组件挂载后
  mounted() {
    console.log('mounted: 组件挂载后');
    // 此时组件已挂载到DOM,可以进行DOM操作
    // 常用作初始化第三方库、DOM操作等
  },
  
  // 5. 数据更新前
  beforeUpdate() {
    console.log('beforeUpdate: 数据更新前');
    // 数据已更新,但DOM尚未重新渲染
  },
  
  // 6. 数据更新后
  updated() {
    console.log('updated: 数据更新后');
    // DOM已重新渲染,可以执行基于新DOM的操作
  },
  
  // 7. 组件卸载前
  beforeUnmount() {
    console.log('beforeUnmount: 组件卸载前');
    // 组件即将卸载,可以进行清理工作
    // 如清除定时器、取消事件监听等
  },
  
  // 8. 组件卸载后
  unmounted() {
    console.log('unmounted: 组件卸载后');
    // 组件已完全卸载,所有事件监听和子组件已移除
  },
  
  data() {
    return {
      message: 'Hello Vue3!'
    };
  },
  
  methods: {
    updateMessage() {
      this.message = 'Vue3生命周期学习中...';
    }
  }
};
</script>

2.2 选项式API生命周期执行顺序

  1. beforeCreate:组件实例初始化前调用,此时无法访问data和methods
  2. created:组件实例创建完成,可访问data和methods,但DOM尚未生成
  3. beforeMount:模板编译完成,准备挂载到DOM
  4. mounted:组件挂载到DOM后调用,可进行DOM操作
  5. beforeUpdate:响应式数据更新时触发,DOM尚未更新
  6. updated:DOM更新完成后触发
  7. beforeUnmount:组件卸载前触发,可进行清理工作
  8. unmounted:组件卸载后触发,所有资源已释放

三、组合式API生命周期

在组合式API中,生命周期钩子需要从vue中显式导入,并在setup函数中使用。

3.1 组合式API生命周期对应关系

选项式API 组合式API 说明
beforeCreate 无(直接在setup中执行) setup函数在beforeCreate和created之间执行
created 无(直接在setup中执行) setup函数在beforeCreate和created之间执行
beforeMount onBeforeMount 组件挂载前调用
mounted onMounted 组件挂载后调用
beforeUpdate onBeforeUpdate 数据更新前调用
updated onUpdated 数据更新后调用
beforeUnmount onBeforeUnmount 组件卸载前调用
unmounted onUnmounted 组件卸载后调用

3.2 组合式API生命周期示例

<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="updateMessage">更新消息</button>
  </div>
</template>

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

// 相当于beforeCreate和created生命周期
console.log('setup: 组件初始化中');

// 定义响应式数据
const message = ref('Hello Vue3 Composition API!');

// 定义方法
const updateMessage = () => {
  message.value = '组合式API生命周期学习中...';
};

// 组件挂载前
onBeforeMount(() => {
  console.log('onBeforeMount: 组件挂载前');
});

// 组件挂载后
onMounted(() => {
  console.log('onMounted: 组件挂载后');
  // 可以进行DOM操作
  const heading = document.querySelector('h1');
  if (heading) heading.style.color = 'blue';
});

// 数据更新前
onBeforeUpdate(() => {
  console.log('onBeforeUpdate: 数据更新前');
  console.log('更新前的值:', message.value);
});

// 数据更新后
onUpdated(() => {
  console.log('onUpdated: 数据更新后');
  console.log('更新后的值:', message.value);
});

// 组件卸载前
onBeforeUnmount(() => {
  console.log('onBeforeUnmount: 组件卸载前');
  // 清理工作
});

// 组件卸载后
onUnmounted(() => {
  console.log('onUnmounted: 组件卸载后');
});
</script>

四、生命周期实际应用场景

4.1 数据初始化与API请求

<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';

const posts = ref([]);
const loading = ref(true);
const error = ref(null);

// 在mounted中发起API请求
onMounted(async () => {
  try {
    const response = await axios.get('https://api.example.com/posts');
    posts.value = response.data;
  } catch (err) {
    error.value = err.message;
  } finally {
    loading.value = false;
  }
});
</script>

4.2 定时器管理

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const count = ref(0);
let timer = null;

onMounted(() => {
  // 组件挂载后启动定时器
  timer = setInterval(() => {
    count.value++;
  }, 1000);
});

onUnmounted(() => {
  // 组件卸载时清除定时器,防止内存泄漏
  if (timer) clearInterval(timer);
});
</script>

4.3 DOM操作与第三方库初始化

<script setup>
import { onMounted } from 'vue';
import Chart from 'chart.js';

onMounted(() => {
  // 在mounted中初始化图表库
  const ctx = document.getElementById('myChart');
  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Red', 'Blue', 'Yellow'],
      datasets: [{
        label: 'Colors',
        data: [12, 19, 3],
        backgroundColor: ['red', 'blue', 'yellow']
      }]
    }
  });
});
</script>

五、注意事项

  1. 避免在updated中修改数据:可能导致无限循环更新

    // 错误示例
    onUpdated(() => {
      // 这会导致无限循环
      message.value = 'Updated';
    });
    
  2. 清理副作用:在onUnmounted中清理定时器、事件监听器等

    onMounted(() => {
      window.addEventListener('resize', handleResize);
    });
    
    onUnmounted(() => {
      window.removeEventListener('resize', handleResize);
    });
    
  3. setup函数执行时机:setup在beforeCreate和created之间执行,无需使用这两个钩子

  4. 组合式API中的生命周期作用域:在组合式API中,生命周期钩子会自动绑定到当前组件实例,无需手动管理

  5. 服务端渲染注意事项:mounted和unmounted钩子在服务端渲染时不会被调用

六、Vue2与Vue3生命周期对比

Vue2生命周期 Vue3选项式API Vue3组合式API 变化说明
beforeCreate beforeCreate setup中直接执行 功能不变
created created setup中直接执行 功能不变
beforeMount beforeMount onBeforeMount 名称不变
mounted mounted onMounted 名称不变
beforeUpdate beforeUpdate onBeforeUpdate 名称不变
updated updated onUpdated 名称不变
beforeDestroy beforeUnmount onBeforeUnmount 名称变更
destroyed unmounted onUnmounted 名称变更
activated activated onActivated 用于KeepAlive组件
deactivated deactivated onDeactivated 用于KeepAlive组件
errorCaptured errorCaptured onErrorCaptured 错误捕获

七、总结

Vue3生命周期提供了组件不同阶段的钩子函数,使我们能够精确控制组件行为。无论是使用选项式API还是组合式API,理解生命周期都是掌握Vue3的关键。

  • 创建阶段:beforeCreate、created(或setup)
  • 挂载阶段:beforeMount、mounted
  • 更新阶段:beforeUpdate、updated
  • 卸载阶段:beforeUnmount、unmounted

合理使用生命周期钩子可以帮助我们编写更高效、可维护的Vue应用,特别是在数据初始化、DOM操作和资源清理方面。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐