请解释 Vue 中的生命周期钩子,不同阶段触发的钩子函数及其用途是什么?

news/2025/2/22 20:56:59

vue生命周期钩子详解(Vue 3版本)

一、生命周期阶段划分

Vue组件的生命周期可分为四大阶段,每个阶段对应特定钩子函数:

  1. 创建阶段:初始化实例并准备数据
  2. 挂载阶段:将虚拟DOM渲染为真实DOM
  3. 更新阶段:响应数据变化并重新渲染
  4. 销毁阶段:清理资源并终止组件
二、核心钩子函数及用途
import { ref, onMounted, onUnmounted } from 'vue';

export default {
  setup() {
    const count = ref(0);

    // 创建阶段
    onMounted(() => {
      console.log('组件已挂载,可操作DOM'); // [1,4,9](@ref)
    });

    // 更新阶段
    watchEffect(() => {
      console.log('数据更新,执行副作用'); // [1,4](@ref)
    });

    // 销毁阶段
    onUnmounted(() => {
      clearInterval(count.value); // [4,9](@ref)
    });

    return { count };
  }
};

1. 创建阶段

  • onMounted:组件挂载完成后触发,适合初始化第三方库、DOM操作
    onMounted(() => {
      const element = document.getElementById('app');
      element.style.color = 'red'; // [4,6](@ref)
    });
  • onBeforeMount:挂载开始前触发,用于模板预处理(Vue 3新增)

2. 挂载阶段

  • onRenderTracked:响应式依赖被追踪时触发(组合式API独有)
    onRenderTracked((event) => {
      console.log('依赖变化:', event.key); // [1,4](@ref)
    });

3. 更新阶段

  • onBeforeUpdate:数据更新但DOM未重绘前触发
    onBeforeUpdate(() => {
      console.log('数据即将更新'); // [4,9](@ref)
    });
  • onUpdated:DOM更新完成后触发
    onUpdated(() => {
      console.log('DOM已更新'); // [4,9](@ref)
    });

4. 销毁阶段

  • onBeforeUnmount:组件销毁前触发,用于清理工作
    onBeforeUnmount(() => {
      clearInterval(count.value); // [4,9](@ref)
    });
  • onUnmounted:组件完全销毁后触发
    onUnmounted(() => {
      console.log('组件已销毁'); // [4,9](@ref)
    });
三、使用建议
  1. 数据请求:优先在onMounted中发起,避免阻塞渲染
    onMounted(async () => {
      const data = await fetchData(); // [4,9](@ref)
      state.value = data;
    });
  2. DOM操作:仅在onMounted/onBeforeUpdate中进行
    onMounted(() => {
      const element = document.getElementById('my-element');
      element.addEventListener('click', handleClick); // [4,6](@ref)
    });
  3. 清理逻辑:必须成对出现(添加/移除事件监听、清除定时器)
    let timer = null;
    onMounted(() => {
      timer = setInterval(() => {}, 1000);
    });
    onBeforeUnmount(() => {
      clearInterval(timer); // [4,9](@ref)
    });
四、注意事项
  1. 避免阻塞主线程:不要在生命周期钩子中执行复杂计算
    // 错误示例:onMounted中执行大数据处理
    onMounted(() => {
      heavyComputation(); // [4,14](@ref)
    });
  2. 正确处理异步操作:使用watchEffectwatch监听数据变化
    watchEffect(() => {
      const data = await fetchData(count.value); // [1,4](@ref)
      state.value = data;
    });
  3. 父子组件生命周期顺序
    父 beforeMount -> 子 beforeMount -> 子 mounted -> 父 mounted
    父 beforeUnmount -> 子 beforeUnmount -> 子 unmounted -> 父 unmounted
  4. 组合式API注意事项
    • onMounted等钩子必须在setup函数内调用
    • 响应式数据需通过refreactive声明
    // 错误示例:未声明响应式数据
    setup() {
      onMounted(() => {
        console.log(nonRefData); // undefined
      });
    }
五、与React useEffect对比
Vue 生命周期React useEffect适用场景
onMounteduseEffect(() => {}, [])组件挂载后执行一次性操作
onBeforeUpdateuseEffect(() => {}, [data])数据更新前执行逻辑
onUnmounteduseEffect的清理函数组件销毁前清理资源

通过合理利用生命周期钩子,开发者可以精确控制组件的行为,提升代码可维护性和性能。在实际开发中,建议结合组合式API的watchEffectwatch实现更细粒度的响应式处理,同时严格遵循"挂载前/后"、"更新前/后"的操作规范,避免常见的内存泄漏和竞态条件问题。


http://www.niftyadmin.cn/n/5862753.html

相关文章

【mysql共享锁与排他锁】

MySQL共享锁(Shared Lock)与排他锁(Exclusive Lock)总结 1. 基本概念 共享锁(S锁) 作用:用于读取操作(读锁)。特点:允许多个事务同时持有共享锁,…

如何保证bug在改完之后不会引起新bug

一、测试前:影响范围分析 代码关联分析:依据开发代码关联性检查获取改动信息,聚焦影响范围,明确代码改动影响的业务功能、是否涉及公共组件或接口,检查 Swagger 文档更新情况。若开发无法明确影响范围,在测…

算法-哈希表篇08-四数之和

四数之和 力扣题目链接 题目描述 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复&…

Python 循环中的隐藏宝藏:Else 子句深度剖析

在 Python 编程里,循环结构是基础且高频使用的部分,不过其中的 else 子句却常被大家忽略。本文将深入、全面地解析 Python 循环中 else 子句的工作原理、使用方法,通过丰富的代码示例、直观的图表,以及与其他相关知识点的对比&…

简讯:Rust 2024 edition and v1.85.0 已发布

详见 https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html 升级方法:rustup update stable

51c大模型~合集69

我自己的原文哦~ https://blog.51cto.com/whaosoft/12221979 #7项基于SAM万物分割模型研究工作 1、CC-SAM: SAM with Cross-feature Attention and Context for Ultrasound Image Segmentation #ECCV2024 #SAM #图像分割 #医学图像 Segment Anything Model (SAM) 在自…

算法:选择排序(以排队为例)

举个栗子🌰:体育课排队 假设体育老师要按身高从高到矮给10个同学排队(降序排序),老师会这样做: 第1轮:找全班最高的同学,让他站在第1个位置第2轮:在剩下的9人中找最高的…

使用Hardhat实现ERC20 代币合约详解

ERC20 代币合约详解 💰 1. 合约概览 // SPDX-License-Identifier: MIT pragma solidity ^0.8.20;import "openzeppelin/contracts/token/ERC20/ERC20.sol";contract MyToken is ERC20 {constructor() ERC20("MyToken", "MTK") {_min…