Vue生命周期

目录

基本概念

[vue 2生命周期](#vue 2生命周期)

创建前后

挂载前后

更新前后

销毁前后

​编辑

代码示例

​编辑

[vue 3生命周期](#vue 3生命周期)

选项式

组合式

代码示例

特殊场景生命周期

[1 .onErrorCaptured](#1 .onErrorCaptured)

[2. activated /onActivated](#2. activated /onActivated)


基本概念

vue实例从创建到销毁的过程就是生命周期。也就是,创建,初始化数据,编译模版,挂载DOM到渲染,更新到渲染,销毁等一系列过程,在这些过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。

主要分为四个阶段:创建前后,挂载前后,更新前后,销毁前后,以及一些特殊场景生命周期


vue 2生命周期

创建前后

1. beforeCreate

在实例初始化(new Vue())之后,进行数据侦听和事件/侦听器的配置之前同步调用。

1.这个阶段,数据是获取不到的,并且真实dom元素也是没有渲染出来的

2.可以在此阶段添加加loading事件,在加载实例时触发

2. created

在实例创建完成后被立即调用。在这一步,实例已完成数据侦听、计算属性和方法的运算、watch/event 事件回调。

1.这个阶段,数据可以访问到了 ,但是**$el(element节点)不可见**,或者说页面当中真实DOM还是没有渲染出来

2.可以在此阶段进行相关初始化事件的绑定、如在这里结束loading事件,也可以进行异步请求操作


挂载前后

3. beforeMount

在挂载开始之前被调用。相关的 render 函数首次被调用。该钩子在服务器端渲染期间不被调用。

1.在这个阶段,完成了DOM的初始化,但仍然无法获取到具体的DOM元素,因为vue还没有进行根节点挂载,但是根节点已经创建完成,下面Vue对DOM的操作将围绕这个根节点进行。

2.beforeMount这个阶段是过渡性的,在项目中使用得比较少

4. mounted

实例被挂载后被调用。此时数据挂载完毕,真实dom元素也已经渲染完成了,也就是能获取到数据和DOM元素了

1.可以在此阶段进行一些实例化相关的操作

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

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

更新前后

5. beforeUpdate

在数据发生改变后,DOM 被更新之前被调用。此阶段的视图数据和DOM元素数据并不同步

1.这里适合在现有 DOM 将要被更新之前访问它,比如移除手动添加的事件监听器。

2.注意:这个钩子函数在挂在完成且数据发生改变后才会被调用,它获取到的是更新前的DOM

6. updated

在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用。这个时候数据发生了改变,并且视图页面也已经完成了更新,因此,该阶段看到的DOM元素的内容是最新内容。

1.当这个钩子被调用时,组件 DOM 已经更新,所以现在可以执行依赖于 DOM 的操作。

2.注意:要避免更改状态,因为这可能会导致无限更新循环。如果要响应状态改变,通常最好使用计算属性或 watcher 。

3.注意updated 会在组件的任意 DOM 更新后被调用,这些更新可能是由不同的状态变更导致的,因为多个状态变更可以在同一个渲染周期中批量执行 (考虑到性能因素)。如果你希望等到整个视图都渲染完毕,可以在 updated 里使用 [vm.nextTick](https://v2.cn.vuejs.org/v2/api/#vm-nextTick "vm.nextTick"):

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

更新过程:

1)数据变化:当Vue组件的数据发生变化时,Vue会开始一个更新过程。

2)虚拟DOM比对 :Vue会基于新的数据生成一个新的虚拟DOM树,并与旧的虚拟DOM树进行比对(这个过程通常称为"diff")。这个比对过程是为了找出需要被更新的真实DOM的最小部分

3)DOM更新:一旦确定了需要更新的部分,Vue会将这些变化应用到真实的DOM上。

4)生命周期钩子在DOM更新之后,Vue会调用updated生命周期钩子 。这意味着,在updated钩子被调用时,组件的DOM已经是最新的状态,反映了最新的数据。


销毁前后

7. beforeDestroy

实例销毁之前调用。在此阶段Vue实例仍然完全可用,包括它的数据(data)、计算属性(computed)、方法(methods)以及 DOM 元素(通过 this.$el 访问)。

此阶段可以手动清理一些副作用,例如计时器、DOM 事件监听器或者与服务器的连接。

8. destroyed

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

Vue实例失去活性,完全丧失功能


上图来自vue2官方文档生命周期图示

代码示例

html 复制代码
<template>
  <div id="app">
    <p id="text">{{msg}}</p>
    <button @click="msgChange()">更新data</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      msg: 'hello'
    }
  },
  methods: {
    msgChange(){
      this.msg ='我更新了'
    }
  },
  beforeCreate(){
    console.log('beforeCreate阶段:');
    console.log(this.msg,this.$el)
  },
  created () {
    console.log('createde阶段:');
    console.log(this.msg, this.$el)
  },
  beforeMount () {
    console.log('beforeMounte阶段:')
    console.log(this.msg,this.$el)
  },
  mounted () {
    console.log('mountede阶段:')
    console.log(this.msg, this.$el)
  },
  beforeUpdate(){
    console.log('beforeUpdate阶段:');
    console.log(this.msg,this.$el.innerHTML)
  },
  updated () {
    console.log('updated阶段:');
    console.log(this.msg, this.$el.innerHTML)
  },
  beforeDestroy(){
    console.log('beforeDestroy阶段:');
    console.log(this.msg, this.$el.innerHTML)
  },
  destroyed(){
    console.log('已销毁');
  }
}
</script>

页面初始化挂载完成后(会触发创建前后,挂在前后4个钩子函数):

页面初始化挂载完成并更新后(会触发更新前后2个钩子函数):


vue 3生命周期

选项式

Vue 3中的选项式生命周期钩子基本上与Vue 2保持一致,它们都是定义在Vue实例的对象参数中的函数,在Vue实例的生命周期的不同阶段被调用。

主要区别如下(其余基本一致):

|--------|-------------------|-------------------|
| 区别 | vue 3选项式 | vue 2 |
| 销毁前 | beforeUnmount | beforeDestroy |
| 销毁后 | unmounted | destroyed |

vue 3选项式中将销毁前后(或者说卸载前后)的周期函数由 "beforeDestroydestroyed "变成了 "beforeUnmountunmounted "。与挂载前后的 "beforeMountmounted" 相互对应。

javascript 复制代码
export default {
  beforeUnmount() {
    console.log('beforeUnmount')
  },
  unmounted() {
    console.log('unmounted')
  }
}

组合式

Vue3的组合式API提供了一套新的生命周期钩子,与Vue2中的选项式生命周期钩子有着对应关系:

|-------|---------------------|-------------------|
| / | vue 3组合式 | vue 2 |
| 创建前后 | setup | beforeCreate |
| 创建前后 | setup | created |
| 挂载前 | onBeforeMount | beforeMounte |
| 挂载后 | onMounted | mounted |
| 更新前 | onBeforeUpdate | beforeUpdate |
| 更新后 | onUpdated | updated |
| 销毁前 | onBeforeUnmount | beforeDestroy |
| 销毁后 | onUnmounted | destroyed |

总的来说:

Vue3 使用 Composition API 引入了新的生命周期钩子,但是它们和 Vue2 中的生命周期钩子有直接的对应关系。vue 3使用setup()来代替 beforeCreate 和 created,并提供了一系列"on"钩子函数。


上图来自vue 3官方文档生命周期图示

代码示例

javascript 复制代码
import { onBeforeMount, onMounted } from 'vue'

export default {
  setup() {
    onBeforeMount(() => {
      console.log('onBeforeMount')
    })
    onMounted(() => {
      console.log('onMounted')
    })

    return {}
  }
}

注意:选项式中周期函数需要引入才能使用

特殊场景生命周期

|-------------------|---------------------|-------------------------|
| Vue 2 | vue 3 | 功能 |
| errorCaptured | onErrorCaptured | 捕获一个来自后代组件的异常时调用 |
| activated | onActivated | 被 keep-alive 缓存的组件激活时调用 |
| deactivated | onDeactivated | 被 keep-alive 缓存的组件停用时调用 |

以vue 3举例:

1 .onErrorCaptured

javascript 复制代码
function onErrorCaptured(callback: ErrorCapturedHook): void

type ErrorCapturedHook = (
  err: unknown,
  instance: ComponentPublicInstance | null,
  info: string
) => boolean | void

在捕获一个来自后代组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

错误可以从以下几个来源中捕获:

  • 组件渲染
  • 事件处理器
  • 生命周期钩子
  • setup() 函数
  • 侦听器
  • 自定义指令钩子
  • 过渡钩子

你可以在 errorCaptured() 中更改组件状态来为用户显示一个错误状态。注意不要让错误状态再次渲染导致本次错误的内容,否则组件会陷入无限循环。


2. activated /onActivated

1.<KeepAlive> 包裹动态组件时,会缓存不活跃的组件实例,而不是销毁它们(提升性能)。同时这些组件将拥有onActivated和onDeactivate两个生命周期。

切换组件时一般情况下会自动销毁组件,对于可能会频繁切换的组件,消耗的性能可能会较大,组件的某些需要缓存的数据也会被初始化。而<KeepAlive>很好的解决了这个问题。

  1. 任何时候都只能有一个活跃组件实例作为 <KeepAlive> 的直接子节点。

  2. 当一个组件在 <KeepAlive> 中被切换时,它的 activated 和 deactivated 生命周期钩子将被调用,用来替代 mounted 和 unmounted。这适用于 <KeepAlive> 的直接子节点及其所有子孙节点。

activated:若组件实例是 <KeepAlive>缓存树的一部分,当组件从 DOM 中被移除时调用。

**onActivated:**若组件实例是 <KeepAlive>缓存树的一部分,当组件被插入到 DOM 中时调用。

javascript 复制代码
<template>
  <KeepAlive>
    <component :is="activeComponent" />
  </KeepAlive>
</template>
<script setup>
import { onActivated, onDeactivated } from 'vue'
let activeComponent = true//控制component是在缓存树还是DOM树

onActivated(() => {
  // 调用时机为首次挂载
  // 以及每次从缓存中被重新插入时
})

onDeactivated(() => {
  // 在从 DOM 上移除、进入缓存
  // 以及组件卸载时调用
})
</script>

更多vue生命周期详细内容: vue 3 组合式 API:生命周期钩子 vue 2 API:生命周期钩子​​​​​​


若有错误或描述不当的地方,烦请评论或私信指正,万分感谢 😃

相关推荐
傻小胖9 分钟前
React 脚手架配置代理完整指南
前端·react.js·前端框架
EterNity_TiMe_21 分钟前
【论文复现】农作物病害分类(Web端实现)
前端·人工智能·python·机器学习·分类·数据挖掘
bohu8335 分钟前
sentinel学习笔记8-系统自适应与黑白名单限流
笔记·sentinel·系统自适应·authorityslot·paramflowslot
余生H41 分钟前
深入理解HTML页面加载解析和渲染过程(一)
前端·html·渲染
滴_咕噜咕噜1 小时前
学习笔记(prism--视频【WPF-prism核心教程】)--待更新
笔记·学习·wpf
吴敬悦1 小时前
领导:按规范提交代码conventionalcommit
前端·程序员·前端工程化
ganlanA1 小时前
uniapp+vue 前端防多次点击表单,防误触多次请求方法。
前端·vue.js·uni-app
卓大胖_1 小时前
Next.js 新手容易犯的错误 _ 性能优化与安全实践(6)
前端·javascript·安全
m0_748246351 小时前
Spring Web MVC:功能端点(Functional Endpoints)
前端·spring·mvc
SomeB1oody1 小时前
【Rust自学】6.4. 简单的控制流-if let
开发语言·前端·rust