Vue生命周期

目录

基本概念

vue 2生命周期

创建前后

挂载前后

更新前后

销毁前后

​编辑

代码示例

vue 3生命周期

选项式

组合式

代码示例

特殊场景生命周期

1 .onErrorCaptured

 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

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

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官方文档生命周期图示

代码示例

<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
销毁前beforeUnmountbeforeDestroy
销毁后unmounteddestroyed

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

export default {
  beforeUnmount() {
    console.log('beforeUnmount')
  },
  unmounted() {
    console.log('unmounted')
  }
}

组合式

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

/vue 3组合式vue 2
创建前后setupbeforeCreate
created
挂载前onBeforeMountbeforeMounte
挂载后onMountedmounted
更新前onBeforeUpdate

beforeUpdate

更新后onUpdated

updated

销毁前onBeforeUnmountbeforeDestroy
销毁后onUnmounteddestroyed

总的来说:

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


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

代码示例

import { onBeforeMount, onMounted } from 'vue'

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

    return {}
  }
}

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

特殊场景生命周期

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

以vue 3举例:

1 .onErrorCaptured

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>很好的解决了这个问题。

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

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

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

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

<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:生命周期钩子​​​​​​

-----------------------------------------------------------------------------------------------------------------------------

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值