Vue 3 生命周期钩子

 前端   大苹果   2024-09-16 22:09   27

在 Vue 3 中,生命周期钩子依然是组件的核心组成部分,用来在组件不同的生命周期阶段执行特定的代码逻辑。Vue 3 中的生命周期钩子发生了变化,不再像 Vue 2 中那样使用特定的选项属性,而是通过 Composition API 提供了函数的形式。

Vue 3 生命周期钩子概览

Vue 3 中的生命周期分为几个阶段,每个阶段都有相应的钩子函数:

  1. 组件创建阶段

    • setup:初始化组件,数据和方法的定义阶段
    • beforeCreate(Options API)
    • created(Options API)
  2. 挂载阶段

    • beforeMount:组件挂载到 DOM 之前
    • mounted:组件挂载到 DOM 之后
  3. 更新阶段

    • beforeUpdate:响应式数据更新且虚拟 DOM 重新渲染前
    • updated:虚拟 DOM 更新并反映到真实 DOM 之后
  4. 卸载阶段

    • beforeUnmount:组件卸载前
    • unmounted:组件卸载后

在 Vue 3 的 Composition API 中,对应的生命周期钩子函数为:

  • onBeforeMount
  • onMounted
  • onBeforeUpdate
  • onUpdated
  • onBeforeUnmount
  • onUnmounted

此外,还有一些特殊的生命周期钩子:

  • onActivated:当使用 <keep-alive> 包裹组件时,组件激活时触发。
  • onDeactivated:当使用 <keep-alive> 包裹组件时,组件停用时触发。
  • onErrorCaptured:捕获子孙组件的错误。

1. 组件创建阶段

beforeCreate & created(Options API)

  • 作用beforeCreatecreated 这两个钩子主要用于初始化组件。在这个阶段,组件实例已经创建,但还没有挂载到 DOM,也没有生成任何模板。此时,数据已经可用(对于 Composition API 来说是 setup 阶段)。
  • 触发时机:在实例被初始化之后,组件还未挂载时。
export default {
  beforeCreate() {
    console.log('beforeCreate: 组件实例刚刚被创建');
  },
  created() {
    console.log('created: 组件实例已创建,但还未挂载');
  }
}

在 Composition API 中,beforeCreatecreated 的作用几乎完全由 setup 替代。

2. 挂载阶段

onBeforeMount

  • 作用:在组件挂载到 DOM 之前调用。此时模板已编译好,但尚未插入到页面中,数据和 DOM 还未结合。
  • 触发时机:挂载组件之前。
import { onBeforeMount } from 'vue';

export default {
  setup() {
    onBeforeMount(() => {
      console.log('beforeMount: 组件即将挂载');
    });
  }
}

onMounted

  • 作用:组件已经被挂载到 DOM 上,所有的 DOM 操作已经完成。在这个阶段,组件的元素可以在页面中被访问,常用于初始化 DOM 交互(如获取 DOM 元素的大小或进行第三方库的初始化)。
  • 触发时机:挂载组件之后。
import { onMounted } from 'vue';

export default {
  setup() {
    onMounted(() => {
      console.log('mounted: 组件已挂载');
    });
  }
}

3. 更新阶段

onBeforeUpdate

  • 作用:组件响应式数据发生变化时,在虚拟 DOM 更新之前调用。此时你可以在组件更新前做一些事情,比如取消某些操作,或处理特定的数据变化。
  • 触发时机:数据发生变化,但还未渲染到页面时。
import { onBeforeUpdate } from 'vue';

export default {
  setup() {
    onBeforeUpdate(() => {
      console.log('beforeUpdate: 组件数据发生变化,虚拟 DOM 即将更新');
    });
  }
}

onUpdated

  • 作用:在组件的虚拟 DOM 重新渲染并更新到真实 DOM 后调用。此时,最新的 DOM 已经反映了最新的数据状态。可以用来执行某些与 DOM 相关的更新后操作。
  • 触发时机:数据发生变化并已经渲染到页面之后。
import { onUpdated } from 'vue';

export default {
  setup() {
    onUpdated(() => {
      console.log('updated: 组件更新完成,DOM 已经更新');
    });
  }
}

4. 卸载阶段

onBeforeUnmount

  • 作用:在组件实例即将被销毁时调用。在这个阶段,组件仍然保留在 DOM 中,通常用于清除定时器或取消订阅等操作。
  • 触发时机:组件即将从 DOM 中卸载时。
import { onBeforeUnmount } from 'vue';

export default {
  setup() {
    onBeforeUnmount(() => {
      console.log('beforeUnmount: 组件即将卸载');
    });
  }
}

onUnmounted

  • 作用:组件被销毁后调用。在这个阶段,组件的 DOM 元素已经被移除,所有的事件监听器、定时器等也被清除,常用于资源的释放和一些清理操作。
  • 触发时机:组件完全从 DOM 中移除之后。
import { onUnmounted } from 'vue';

export default {
  setup() {
    onUnmounted(() => {
      console.log('unmounted: 组件已卸载');
    });
  }
}

5. 特殊的生命周期钩子

onActivated & onDeactivated

  • 作用:当组件被 <keep-alive> 包裹时,这两个钩子用于处理组件的激活和停用。onActivated 在组件从缓存中被激活时触发,onDeactivated 在组件被缓存时触发。
  • 触发时机
    • onActivated:组件被 <keep-alive> 缓存并再次激活时触发。
    • onDeactivated:组件被 <keep-alive> 缓存时触发。
import { onActivated, onDeactivated } from 'vue';

export default {
  setup() {
    onActivated(() => {
      console.log('组件已激活');
    });

    onDeactivated(() => {
      console.log('组件已停用');
    });
  }
}

onErrorCaptured

  • 作用:在组件中捕获到子组件的错误时触发,可以进行错误处理。常用于错误边界设计。
  • 触发时机:子组件发生错误时。
import { onErrorCaptured } from 'vue';

export default {
  setup() {
    onErrorCaptured((err, instance, info) => {
      console.error('捕获到错误:', err);
    });
  }
}

Vue 3 生命周期触发顺序

Vue 3 生命周期的触发顺序如下:

  1. beforeCreate (Options API)
  2. created (Options API)
  3. setup (Composition API)
  4. beforeMount
  5. onBeforeMount
  6. mounted
  7. onMounted
  8. beforeUpdate
  9. onBeforeUpdate
  10. updated
  11. onUpdated
  12. beforeUnmount
  13. onBeforeUnmount
  14. unmounted
  15. onUnmounted

应用场景示例

1. onMounted:初始化第三方插件

import { onMounted } from 'vue';

export default {
  setup() {
    onMounted(() => {
      // 假设初始化一个第三方库
      initializeThirdPartyLibrary();
    });
  }
}

2. onBeforeUnmount:清除定时器

import { onBeforeUnmount, ref } from 'vue';

export default {
  setup() {
    const intervalId = ref(null);

    const startTimer = () => {
      intervalId.value = setInterval(() => {
        console.log('计时中...');
      }, 1000);
    };

    onBeforeUnmount(() => {
      clearInterval(intervalId.value);
      console.log('组件卸载,定时器已清除');
    });

    return { startTimer };
  }
}

3. watchEffectonUpdated:监控 DOM 更新

import { ref, watchEffect, onUpdated } from 'vue';

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

    watchEffect(() => {
      console.log('响应式数据变化: ', count.value);
    });

    onUpdated(() => {
      console.log('DOM 已更新');
    });

    const increment = () => {
      count.value++;
    };

    return

 { count, increment };
  }
}

总结

Vue 3 提供了更加简洁、灵活的生命周期管理方式,尤其是 Composition API 中通过 onX 系列函数的调用,使得生命周期管理变得更加直观和简便。通过了解和合理使用这些生命周期钩子,可以让你的组件更加健壮、维护更容易。