你必须知道的 Vue 3 组件生命周期

1,140 阅读5分钟

引言

本次,我们将深入探讨Vue.js中生命周期钩子的精妙之处,为开发者提供一个全面理解组件生命历程的机会。从组件的初始化到最终的销毁,Vue的生命周期给予我们多个关键时刻来介入和定制组件的行为。

56665.jpg

基础准备

在node环境下使用vite创建一个vue项目。

npm init vite
cd 你的文件夹
npm i

下面是文件结构

image.png

v-if vs v-show

让我们分析一下 v-ifv-show 的区别。这两个指令都可以用来根据条件渲染元素或组件,但它们的工作原理不同。这将对我们理解生命周期有很大的帮助。

  • v-if: 这个指令会根据表达式的真假值来决定是否真正地渲染元素或组件。如果条件为假,那么元素或组件将不会被添加到 DOM 中;当条件首次变为真时,组件会经历完整的生命周期钩子。

  • v-show: 不管条件真假都会渲染元素或组件,只是通过 CSS 的 display 属性来控制其可见性。因此,使用 v-show 的组件会始终存在于 DOM 中,即使不可见也不会影响其生命周期。

下面我直接给出代码(我们先使用v-if

App.vue文件

<script setup>
import LifecycleComponent from './components/LifecycleComponent.vue'
import { ref } from 'vue';
const showComponent = ref(true); 
const toggleComponent = ()=>{
  showComponent.value = !showComponent.value
}
const count = ref(0);
const incrementCount = ()=>{
  count.value++ 
}
</script>

<template>
  <div>
    <button @click="toggleComponent">Toggle Component</button> 
    <button @click="incrementCount">Increment Component</button>
    <p>Count:{{ count }}</p>
    <LifecycleComponent v-if="showComponent" :count="count"/>
  </div>
</template>

<style scoped>
</style>

LifecycleComponent.vue文件

<template>
  <div>
    <div>
      <p id="count">Lifecycle Component - Count:{{ count }}</p>
    </div>
  </div>
</template>

<script setup>
import { 
  defineProps,
} from 'vue';
defineProps({
  count:{
    type:Number,
    required:true  // 必须有
  }
})
</script>

<style scoped>
</style>

我们使用浏览器的vue.js devtools插件来检查vue组件树, image.png

点击Toggle Component按钮后,注意看组件树的变化。 image.png

与上面介绍的一样,当v-iffalse时,不会添加这个组件。

我们把上面代码中的v-if改成v-show,其他部分不变。

<LifecycleComponent v-show="showComponent" :count="count"/>

点击Toggle Component按钮后,LifecycleComponent组件仍然在组件树上,只是看不见了。v-show只是给这个元素设置了display:none样式,并没有像v-if一样,把组件销毁掉。 image.png

image.png

组件生命周期

由上面的v-ifv-show可以看出,每个组件都是有生命周期的,会生老病死。

组件生命周期指的是组件从创建到销毁所经历的一系列阶段。每个阶段都有相应的钩子函数,允许我们在特定的时间点执行代码,如初始化数据、响应状态变化或清理资源等。

了解并正确使用这些生命周期钩子,对于优化应用性能、确保代码的可维护性至关重要。

组件是一个类

在 Vue.js 中,组件可以被理解为具有特定功能和外观的可复用 UI 构建块,它们更像是配置对象而非传统意义上的类。每个组件都有自己的状态、行为和生命周期钩子,能够封装逻辑并独立于其他组件运作。

一个完整的 Vue 组件通常包含三个部分:模板 (<template>), 样式 (<style>), 和脚本 (<script>)。模板描述了组件的结构,样式控制外观,脚本则包含了逻辑。

当一个组件被注册并在父组件中使用时,它会被挂载到 DOM 中指定的位置。这个过程包括初始化组件的状态、解析模板、应用样式,以及最终将组件的内容渲染到浏览器页面上。Vue 使用虚拟 DOM 来高效地更新界面,确保只对必要的部分进行重新渲染。

生命周期阶段

Vue 3 组件的生命周期可以分为几个主要阶段,这些阶段代表了组件在其存在期间经历的不同状态:

  1. 创建 (Creation)

    • 这是组件实例被创建的阶段,在这个阶段中,Vue 初始化数据观测、事件配置等。
    • 包含 beforeCreatecreated 钩子。
  2. 挂载 (Mounting)

    • 在此阶段,组件第一次渲染到页面上。
    • 包含 beforeMountmounted 钩子。
  3. 更新 (Updating)

    • 当组件的数据发生变化时,会触发更新阶段。在此阶段,组件会根据新的数据重新渲染。
    • 包含 beforeUpdateupdated 钩子。
  4. 卸载 (Unmounting)

    • 当组件从 DOM 中移除时进入此阶段。在这一阶段,组件将清理它自己,例如移除事件监听器和取消网络请求。
    • 包含 beforeUnmountunmounted 钩子。
  5. 错误处理 (Error Handling)

    • 如果后代组件抛出了一个未捕获的错误,父组件的 errorCaptured 钩子会被调用。
  6. 调试 (Debugging)

    • Vue 3 提供了两个专门用于调试的钩子:renderTrackedrenderTriggered,它们提供了对响应式依赖追踪和组件重渲染触发原因的可见性。

示例说明

LifecycleComponent文件

<template>
  <div>
    <p id="count">Lifecycle Component - Count:{{ count }}</p>
  </div>
</template>

<script setup>
// lifecycle 生命周期
import { 
  defineProps,
  onBeforeMount,
  onMounted,
  onBeforeUnmount,
  onUnmounted,
  onBeforeUpdate,
  onUpdated 
} from 'vue';
defineProps({
  count:{
    type:Number,
    required:true  // 必须有
  }
})
onBeforeMount(()=>{
  console.log(document.getElementById('count'),'---1---');  // null 
  console.log('挂载之前');
})
// 组件有生老病死 
// 生命周期
onMounted(()=>{
  // on 某个阶段
  // mounted 挂载
  // 已经完成了挂载
  console.log('已经挂载');
    console.log(document.getElementById('count'),'---2---');
})
onBeforeUnmount(()=>{
  console.log('卸载之前');
})
onUnmounted(()=>{
  console.log('卸载');
})
onBeforeUpdate(()=>{
  console.log('更新之前');
})
onUpdated(()=>{
  console.log('更新之后');
})
</script>

v-if时,可以看到组件的挂载、卸载和更新。 1735878548953.gif

v-show时,只能看到组件的挂载、更新。因为v-if是把组件销毁了,而v-show只是将组件的样式更新为display:none

1735879361750.gif

总结

以上是对 Vue 3 组件生命周期的一个全面介绍。希望这篇文章能加深你对这一主题的理解,并为你开发高质量的 Vue 应用提供指导。如果你有任何疑问或者需要进一步的帮助,请随时提问!

sdffs.jpg