likes
comments
collection
share

Vue 文档解读(一): 生命周期与钩子函数

作者站长头像
站长
· 阅读数 52

相信大家对 Vue 的使用应该很熟悉了,那大家在使用 Vue 的一些钩子函数时,是否对其底层的原理知晓呢?如Vue的生命周期,以及浏览器中 DOM 树的形成及网页的渲染过程呢?这些都是 Vue 很基础的原理,以及面试的常考点。因此,本文将详细讲解 Vue 生命周期与 DOM 树形成、网页渲染的关系,帮助大家全面理解 Vue 是如何在浏览器中形成网页的。

浏览器渲染流程概述

在探讨 Vue 生命周期与网页渲染的关系之前,先了解一下浏览器渲染流程:

  • 解析 HTML:浏览器解析 HTML 文档,生成 DOM 树。

  • 解析 CSS:解析 CSS,生成 CSSOM 树。

  • 构建渲染树:将 DOM 树和 CSSOM 树结合,生成渲染树。

  • 布局:计算渲染树每个节点的布局(位置和大小)。

  • 绘制:将渲染树的节点绘制到屏幕上。

DOM 树如下图所示:

 Vue 文档解读(一): 生命周期与钩子函数

什么是 Vue 生命周期

Vue 组件从创建到销毁的过程中,会经历一系列的初始化、渲染、更新和销毁的过程,这就是组件的生命周期。Vue 提供了一些钩子函数,让开发者在组件的不同阶段执行特定的操作。

Vue 生命周期钩子函数

Vue 生命周期钩子函数按顺序可以分为以下几个阶段:

  • 创建阶段 (Creation)

    • onBeforeMount
    • onMounted
  • 更新阶段 (Updating)

    • onBeforeUpdate
    • onUpdated
  • 销毁阶段 (Destruction)

    • onBeforeUnmount
    • onUnmounted
  • 错误处理

    • onErrorCaptured
  • 渲染处理

    • onRenderTracked
    • onRenderTriggered
  • 激活/停用

    • onActivated
    • onDeactivated
  • 服务端预取

    • onServerPrefetch

Vue 生命周期与 DOM 树形成及网页渲染的关系

每个生命周期钩子函数在 Vue 组件的不同阶段被调用,与浏览器的 DOM 树形成和网页渲染过程紧密相关。下面将详细解释一些常用的钩子函数:

创建阶段

onBeforeMount

在挂载开始之前被调用。此时组件还未挂载到 DOM,虚拟 DOM 已生成。

import { onBeforeMount } from 'vue';
onBeforeMount(() => { console.log('onBeforeMount: 挂载开始之前被调用'); });
onMounted

在组件挂载到 DOM 后立即调用。适合在此进行 DOM 操作或数据请求。

import { onMounted } from 'vue';
onMounted(() => { console.log('onMounted: 组件挂载到 DOM 后被调用'); });

在这个阶段,浏览器将解析 HTML 并生成初始的 DOM 树。Vue 将模板编译成虚拟 DOM,并将其挂载到实际的 DOM 树上,浏览器完成首次渲染。

更新阶段

onBeforeUpdate

在数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。

import { onBeforeUpdate } from 'vue';
onBeforeUpdate(() => { console.log('onBeforeUpdate: 数据更新时被调用'); });
onUpdated

在由于数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用。适合在此进行依赖于 DOM 更新的操作。

import { onUpdated } from 'vue';
onUpdated(() => { console.log('onUpdated: 虚拟 DOM 重新渲染和打补丁之后被调用'); });

当组件的数据发生变化时,Vue 会重新计算虚拟 DOM,并将其与上一次的虚拟 DOM 进行比较,找出变化的部分,然后更新实际的 DOM 树。这一过程称为打补丁(patching)。浏览器会重新计算渲染树,并重新布局和绘制页面。

销毁阶段

onBeforeUnmount

在实例销毁之前调用。适合在此进行清理操作,如移除事件监听器或清除定时器。

import { onBeforeUnmount } from 'vue';
onBeforeUnmount(() => { console.log('onBeforeUnmount: 实例销毁之前被调用'); });
onUnmounted

在实例销毁之后调用。所有事件监听器会被移除,所有子实例也会被销毁。

import { onUnmounted } from 'vue';
onUnmounted(() => { console.log('onUnmounted: 实例销毁之后被调用'); });

在这个阶段,Vue 会移除组件的所有绑定和事件监听器,并从 DOM 树中移除组件的根元素。浏览器会更新 DOM 树,并重新计算渲染树和布局。

激活/停用

onActivated

在 keep-alive 组件激活时调用。

import { onActivated } from 'vue';
onActivated(() => { console.log('onActivated: 组件被激活'); });
onDeactivated

在 keep-alive 组件停用时调用。

import { onDeactivated } from 'vue';
onDeactivated(() => { console.log('onDeactivated: 组件被停用'); });

错误处理

onErrorCaptured

当捕获一个来自子孙组件的错误时被调用。可以返回 false 以阻止该错误继续向上传播。

import { onErrorCaptured } from 'vue';
onErrorCaptured((err, instance, info) => {
      console.log('onErrorCaptured: 捕获到错误', err, instance, info);
      return false; // 阻止错误继续传播
    });

渲染处理

onRenderTracked

在虚拟 DOM 进行跟踪时调用,主要用于调试。

import { onRenderTracked } from 'vue'; 

    onRenderTracked((e) => {
      console.log('onRenderTracked: 虚拟 DOM 进行跟踪', e);
    });
onRenderTriggered

在虚拟 DOM 渲染触发时调用,主要用于调试。

import { onRenderTriggered } from 'vue';

 
    onRenderTriggered((e) => {
      console.log('onRenderTriggered: 虚拟 DOM 渲染触发', e);
    });

完整的生命周期钩子函数使用

以下是一个包含所有生命周期钩子函数的 Vue 组件示例:

<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered, onActivated, onDeactivated, onServerPrefetch } from 'vue';

export default {
  setup() {
    const message = ref('Hello Vue 3!');

    onBeforeMount(() => {
      console.log('onBeforeMount: 挂载开始之前被调用');
    });

    onMounted(() => {
      console.log('onMounted: 组件挂载到 DOM 后被调用');
    });

    onBeforeUpdate(() => {
      console.log('onBeforeUpdate: 数据更新时被调用');
    });

    onUpdated(() => {
      console.log('onUpdated: 虚拟 DOM 重新渲染和打补丁之后被调用');
    });

    onBeforeUnmount(() => {
      console.log('onBeforeUnmount: 实例销毁之前被调用');
    });

    onUnmounted(() => {
      console.log('onUnmounted: 实例销毁之后被调用');
    });

    onErrorCaptured((err, instance, info) => {
      console.log('onErrorCaptured: 捕获到错误', err, instance, info);
      return false;
    });

    onRenderTracked((e) => {
      console.log('onRenderTracked: 虚拟 DOM 进行跟踪', e);
    });

    onRenderTriggered((e) => {
      console.log('onRenderTriggered: 虚拟 DOM 渲染触发', e);
    });

    onActivated(() => {
      console.log('onActivated: 组件被激活');
    });

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

    onServerPrefetch(() => {
      console.log('onServerPrefetch: 服务端预取数据');
    });

    return {
      message
    };
  }
};
</script>

<style scoped>
h1 {
  color: #42b983;
}
</style>

通过这个简单的例子,我们可以看到 Vue 组件从创建、更新到销毁的整个生命周期过程:

  1. 创建阶段onBeforeMountonMounted 分别在组件挂载到 DOM 前后被调用,进行初始化和初次渲染的操作。
  2. 更新阶段onBeforeUpdateonUpdated 在响应式数据更新前后被调用,进行更新前的准备和更新后的处理。
  3. 销毁阶段onBeforeUnmountonUnmounted 在组件实例销毁前后被调用,进行清理操作。

总结

通过本文的学习,我们深入理解了 Vue 3 组件的生命周期钩子函数及其在浏览器中的实际应用。我们通过具体代码示例,解析了组件从创建、挂载、更新到销毁的整个过程。

掌握这些生命周期钩子函数,不仅有助于我们在实际开发中更有效地管理组件,还能帮助我们更好地调试和维护代码。希望本文能够帮助你在 Vue 3 的使用过程中更加得心应手,为你的前端开发工作带来更多的灵感和帮助。写文章不易,可以给文章点个赞哦😊。

转载自:https://juejin.cn/post/7399587895369629711
评论
请登录