vue3.x教程-生命周期

介绍

什么是vue生命周期?

Vue 实例 从创建到销毁的过程,就是生命周期

从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等⼀系列过程,称之为 Vue 的生命周期。

vue生命周期的作用是什么?

生命周期中有多个事件钩⼦,可以在 Vue实例的过程中,更容易添加功能

vue生命周期总共有几个阶段?

分为8个阶段:

  1. 创建前/后
  2. 载⼊前/后
  3. 更新前/后
  4. 销毁前/销毁后

组合式 API setup 生命周期

setup 中没有 beforeCreate / created,代码直接写在 setup 内部等价于这两个钩子。
需要手动导入生命周期函数:

import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted
} from 'vue'

对应关系对照表

选项式 setup 组合式 执行时机
beforeCreate setup 顶部代码 实例初始化,无data
created setup 顶部代码 data/methods 就绪,无DOM
beforeMount onBeforeMount DOM 挂载前
mounted onMounted DOM 挂载完成
beforeUpdate onBeforeUpdate 数据更新,DOM重绘前
updated onUpdated DOM 更新完成
beforeUnmount onBeforeUnmount 组件销毁前
unmounted onUnmounted 组件销毁完成

例子

为了测试组件的卸载前、卸载后,需要定义 Student 子组件,还需要修改 app 父组件,在 app 父组件中增加 卸载子组件的按钮,如下图:

student子组件

HTML代码:

<template>
    <div id="box">
        年龄:{{age}}<br>
        <button @click="addAge">年龄加1</button>
    </div>
</template>

TS代码:

<script lang="ts" setup name='Student'>    
    import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'

    let age = ref(20)

    function addAge(){
        age.value++
    }
    console.log("student---创建-----------")

    onBeforeMount(()=>{
        console.log("student---onBeforeMount挂载前-----------------------")
        const box = document.getElementById("box")
        console.log("box:",box)
    })
    onMounted(()=>{
        console.log("student---onMounted 挂载后-----------------------")
        const box = document.getElementById("box")
        console.log("box:",box)
    })
    onBeforeUpdate(()=>{
        console.log("student---onBeforeUpdate 更新前-----------------------")
        const box = document.getElementById("box")
        console.log("box:",box)
    })
    onUpdated(()=>{
        console.log("student---onUpdated 更新后-----------------------")
        const box = document.getElementById("box")
        console.log("box:",box)
    })
    onBeforeUnmount(()=>{
        console.log("student---onBeforeUnmount 卸载前-----------------------")
        const box = document.getElementById("box")
        console.log("box:",box)
    })
    onUnmounted(()=>{
        console.log("student---onUnmounted 卸载后-----------------------")
        const box = document.getElementById("box")
        console.log("box:",box)
    })

</script>

app组件

<template>
  <Student v-if="show" style="border: 1px red solid;"/>
  <button @click="handle">销毁组件(app组件)</button>
</template>
<script setup lang="ts">
    import Student from './components/Student.vue'
    import {ref} from 'vue'
    let show = ref(true)
    function handle(){
        show.value = false
    }
</script>
<style scoped>

</style>

测试1:刷新页面

刷新页面,显示如下,执行以下生命周期:

1.创建
2.挂载前,挂载前获取不到dom
3.挂载后

测试2:修改值

点击【年龄加1】按钮,修改值,执行以下生命周期:

4.更新前
5.更新后

显示如下:

测试3:销毁

点击【销毁组件】按钮,执行以下生命周期:

6.卸载前
7.卸载后,挂载后获取不到dom

如下图:

执行顺序总结(单组件)

  1. setup 内部代码(beforeCreate + created)
  2. onBeforeMount
  3. onMounted
  4. 数据改变 → onBeforeUpdate → onUpdated
  5. 组件销毁 → onBeforeUnmount → onUnmounted

父子组件生命周期

挂载顺序

父 setup → 父 onBeforeMount → 子 setup → 子 onBeforeMount → 子 onMounted → 父 onMounted

例子

修改 app.vue 组件

<template>
  <Student v-if="show" style="border: 1px red solid;"/>
  <button @click="handle">销毁组件(app组件)</button>
</template>
<script setup lang="ts">
    import Student from './components/Student.vue'
    import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
    let show = ref(true)
    function handle(){
        show.value = false
    }

    console.log("父---创建-----------")

    onBeforeMount(()=>{
        console.log("父---onBeforeMount挂载前-----------------------")
    })
    onMounted(()=>{
        console.log("父---onMounted 挂载后-----------------------")
    })
    onBeforeUpdate(()=>{
        console.log("父---onBeforeUpdate 更新前-----------------------")
    })
    onUpdated(()=>{
        console.log("父---onUpdated 更新后-----------------------")
    })
    onBeforeUnmount(()=>{
        console.log("父---onBeforeUnmount 卸载前-----------------------")
    })
    onUnmounted(()=>{
        console.log("父---onUnmounted 卸载后-----------------------")
    })
</script>
<style scoped>

</style>

刷新页面,打印如下:

更新顺序

父数据更新:父 beforeUpdate → 父 updated
子数据更新:子 beforeUpdate → 子 updated

销毁顺序

父 onBeforeUnmount → 子 onBeforeUnmount → 子 onUnmounted → 父 onUnmounted

应用场景

  1. 初始接口请求:created / setup 内部 / onMounted
  2. 获取DOM元素、图表初始化:onMounted
  3. 清除定时器、窗口监听:onBeforeUnmount
  4. 缓存页面每次进入刷新数据:onActivated
  5. 数据变更后获取最新DOM尺寸:onUpdated

总结

第一次页面加载会触发哪几个钩⼦?

会触发:beforeCreate, created, beforeMount, mounted 。

DOM 渲染在 哪个周期中就已经完成?

DOM 渲染在 mounted 完成

构造函数 与 data、methods

获取不到 data、不能调用 methods中函数 的钩子函数:

  • beforeCreate

能获取到 data、可以调用 methods中函数 的钩子函数(beforeCreate 之后都能获取到):

  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed

钩子函数 与 DOM 对象

获取不到 DOM 对象 的钩子函数:

  • beforeCreate
  • created
  • beforeMount
  • beforeUpdate
  • beforeDestroy
  • destroyed

能获取到 DOM 对象 的钩子函数:

  • mounted
  • updated

原文出处:/show_1GW3i51WmDNC.html