vue选项式api的生命周期

2023/5/23 DOM钩子函数

Vue的生命周期是很重要的一个部分,理解这部分内容有利于我们更加了解vue的工作原理,这篇文章就来记录一下vue的生命周期(选项式API

注意:vue2vue3的生命周期是有区别的,这里只给出了选项式API中最重要的 8 个生命周期钩子函数

📝 vue官网对生命周期的描述

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

总结一下,就是在vue从创建实例到最终销毁的过程中,会经历不同的阶段,在每个阶段时会执行不同的函数,这些函数就叫做 —— 生命周期钩子函数

# beforeCreate

在我们创建一个vue实例之后,首先要执行的就是初始化的工作,那就要搞明白初始化了哪些东西

第一次初始化,实例有了事件,比如.once, .trim这些事件修饰符,有了生命周期函数

何处调用?

会在实例初始化完成、props 解析之后、data()computed 等选项处理之前立即调用。

组合式API中的setup()钩子会在所有选项式API钩子之前调用,beforeCreate()也是这样

图片1

# created

第二次初始化,此时在vue实例上可以看到_data,同时实例对象上可以看到对应的代理属性,计算属性,方法和侦听器

何处调用?

在组件实例处理完所有与状态相关的选项后调用。

# 编译模板阶段

在初始化之后,会检查有没有配置el,也就是vue实例应该挂载到哪个位置(要服务的容器),比如el : root,那就会去找idroot的元素,

此时需要判断有没有配置el

  • 如果没有,就会进入等待,直到vm.$mount(要服务的容器)执行,如果不执行该语句,那就永远不会进行到后边的阶段
  • 如果有,那就进行下一步检查

直到要服务的容器找到后,开始检查是否配置了template

  • 如果有,直接编译template中的内容作为模板(注意要写成单根组件),进行渲染
  • 如果没有,就把el(要服务的容器)外部的html中的模板编译为模板 —— 也就是div id = "root"中的所有内容

这个过程 vue 开始了编译模板的工作,生成虚拟DOM(内存中),所以页面中会显示html渲染后的结果,但不会显示解析好的内容

图片2

# beforeMount

在编译完模板之后,马上要进行的是挂载工作

在挂载之前,此时呈现的是未经过 Vue 编译的 DOM,你可以对 DOM 进行操作,但这些操作最终都不会有效果,(如果你停在这个钩子函数这里,可以看到效果,但是在整个过程中,你修改的 DOM 都会在转换成真实 DOM 后被替换,所以在这里操作 DOM 是没有意义的)

此时组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点,它即将首次执行 DOM 渲染过程。

何处调用?

在挂载开始之前被调用

图片3

# mounted

此时页面呈现的是经过Vue编译的DOM,此时可以操作DOM了(但是不建议),至此页面的整个初始化过程结束

所以一般会在这个钩子函数中开启定时器,发送网络请求,订阅消息,绑定自定义事件等初始化操作

何处调用?

挂载之后调用,并且这时 el 被新创建的 vm.$el 替换了

mounted 不会保证所有的子组件也都被挂载完成。如果你希望等到整个视图都渲染完毕再执行某些操作,可以在 mounted 内部使用 vm.$nextTick

mounted: function () {
  this.$nextTick(function () {
    // 仅在整个视图都被渲染之后才会运行的代码
  })
}

# beforeUpdate

何处调用?
在组件即将因为一个响应式状态变更而更新其 DOM 树之前调用。

在这个钩子函数中适合在现有 DOM 将要被更新之前访问它,比如移除手动添加的事件监听器。
也可以用来在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中更改状态也是安全的。

图片4

# updated

父组件的更新钩子将在其子组件的更新钩子之后调用。

这个钩子会在组件的任意 DOM 更新后(随便哪个更新)被调用,这些更新可能是由不同的状态变更导致的。如果你需要在某个特定的状态更改后访问更新后的 DOM,请使用 nextTick() 作为替代。

不要在updated钩子中修改组件的状态,可能会导致无限循环

何处调用?

在组件因为一个响应式状态变更而更新其 DOM 树之后调用。

updated 也不会保证所有的子组件也都被重新渲染完毕。如果你希望等到整个视图都渲染完毕,可以在 updated 里使用 vm.$nextTick

mounted: function () {
  this.$nextTick(function () {
    // 仅在整个视图都被渲染之后才会运行的代码
  })
}

# beforeDestroy

在该钩子函数中,实例仍然完全可用,可以访问数据和方法,但所有对数据的修改就没用了,但是此时操作实例也是没有意义的,因为实例马上就要销毁了

在这个钩子函数中一般会执行关闭定时器,取消订阅消息,解绑自定义事件等收尾操作

何处调用?

实例销毁之前调用

图片5

# destroyed

该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。

销毁后通过Vue dev tool看不到任何信息

原生的DOM事件只要绑定了就去除不掉了,vue实例销毁了之后,原生的DOM事件仍然是可以调用的,比如buttonclick事件

何处调用?

实例销毁后调用

# 总结

常用的生命周期钩子

  1. mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
  2. beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
How to love
Lil Wayne