Vue生命周期 11个钩子

Vue生命周期 11个钩子Vue 实例有一个完整的生命周期 也就是说从开始创建 初始化数据 编译模板 挂在 DOM 渲染 更新 渲染 卸载等一系列过程 我们称为 Vue 实例的生命周期 钩子函数 附上网上找的一张图解释 当我们 new vue 的时候 这些函数就会自动执行 生命周期钩子的 11 个阶段 创建 beforeCreate

大家好,我是讯享网,很高兴认识大家。

Vue实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂在DOM、渲染-更新-渲染、卸载等一系列过程,我们称为Vue 实例的生命周期(钩子函数)
在这里插入图片描述
讯享网
附上网上找的一张图解释
当我们 new vue 的时候,这些函数就会自动执行

生命周期钩子的11个阶段:

创建:
beforeCreate – 数据初始化前
created – 数据初始化之后
挂载:
beforeMount – 数据准备渲染
Mounted – 数据渲染完成
运行:
beforeUpdata – 数据更新前
updated – 数据更新
销毁:
beforeDestroy – 结束之前执行
destroyed – 执行结束
缓存:
activated – 组件激活时执行
deactivated – 组件停用时执行
错误处理:
errorCaptured – 错误处理机制

构建vue实例

 var vm = new Vue({ 
    el:"#app", data:{ 
    circle:"生命周期" }, 

讯享网

beforeCreate – 数据初始化前
在实例初始化之后,数据观测和event|watcher事件配置之前使用,
这个时期,this变量还不能使用,在data下面的数据和methods下面的方法,watcher中的事件都获取不到。

可以在这里加一个loading事件,在实例加载的时候触

讯享网 beforeCreate(){ 
    console.group("beforeCreate 创建状态,初始化前"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log(this.$el);//undefined console.log("%c%s","color:skyblue","el:"+this.$el);//el:undefined console.log("%c%s","color:green","data:"+this.$data);//data:undefined console.log("%c%s","color:blue","message:"+this.circle);//message:undefined }, 

在这里插入图片描述
created – 数据初始化之后
实例已经创建完成之后被调用,在这一步,实例已经完成以下的配置,数据观测,属性和方法的运算,event|watcher事件回调;但是,挂载阶段还没有开始,$el属性还不可见,这个时候可以操作vue实例中的数据和各种方法.但是还不能对DOM节点进行操作

初始化完成时的事件写在这里,比如在这里结束loading事件,异步请求也可以在这里调用

created(){ 
    console.group("created 创建状态,初始化后"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log("%c%s","color:skyblue","el:"+this.$el);//el:undefined console.log(this.$el);//undefined console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期 }, 

在这里插入图片描述
beforeMount – 数据准备渲染
在挂载开始之前被调用,相关的render函数首次被调用

这个时候可以获取到DOM节点,但还不能进行操作

讯享网 beforeMount(){ 
    console.group("beforeMount 创建状态,准备渲染"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement] console.log(this.$el);//<div id="app" >...</div> console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期 }, 

在这里插入图片描述

Mounted – 数据渲染完成
el 被新创建的vm.$el替换并挂载到实例上去之后调用这个钩子,如果root实例挂载了一个文档内元素,当Mounted被调用时,vm. $el也在文档中。

挂载完毕,DOM节点被渲染到文档中,DOM操作可以正常进行

 mounted(){ 
    console.group("mounted 创建状态,渲染完成"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement] console.log(this.$el);//<div id="app" >...</div> console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期 }, 

在这里插入图片描述
beforeUpdata – 数据更新前
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

这里获取到data的数据是已经更新之后的数据,但还没渲染到文档流中,所以如果在这里获取DOM节点,得到的是未更新的数据。

讯享网 beforeUpdata(){ 
    console.group("beforeUpdata 执行状态,数据更新前"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement] console.log(this.$el);//<div id="app" >...</div> console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期 }, 

updated – 数据更新
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher取而代之。

数据更新已经完成

 updated(){ 
    console.group("updated 执行状态,数据更新"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement] console.log(this.$el);//<div id="app" >...</div> console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期 }, 

在这里绑定了一个按钮,改变数据
更新前 beforeUpdata:

在这里插入图片描述
点击更新后 updated :
在这里插入图片描述
在这里插入图片描述
beforeDestroy – 结束之前执行
在实例销毁之前调用,实例仍然完全可用,这一步还可以用this来获取实例,一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件

讯享网beforeDestroy(){ 
    console.group("beforeDestroy 销毁状态,销毁前执行"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement] console.log(this.$el); console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期 }, 

在这里插入图片描述
destroyed – 执行结束
在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用

destroyed(){ 
    console.group("destroyed 销毁状态,销毁完成"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement] console.log(this.$el); console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期 }, 

在这里插入图片描述
activated 和 deactivated(组件激活时和停用时执行)
这两个钩子需要配合配合来使用
keep-alive的作用会缓存不活动的组件实例,而不是销毁它们。当组件在内被切换,activated和deactivated这两个生命周期钩子函数将会被对应执行。

在这里我搭建了一个脚手架,新建2个子组件,1个父组件
子组件A内容

讯享网<template> <div> <div>componentA</div> <button @click="show=!show" >componentA事件</button> <div v-if='show'>componentA-2</div> <div v-else>componentA-1</div> </div> </template> <script> export default { 
    name: 'componentA', comments: { 
   }, data() { 
    return { 
    show: true, circle:'生命周期' } }, activated() { 
    console.group("activated 组件激活时执行 "); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log(this.$el);//<div id="app" >...</div> console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement] console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:undefined }, deactivated() { 
    console.group("deactivated 组件停用时执行"); console.log("%c%s","color:pink",this);//this指向vue的实例 console.log(this.$el);//<div id="app" >...</div> console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement] console.log("%c%s","color:green","data:"+this.$data);//data:[object Object] console.log("%c%s","color:blue","message:"+this.circle);//message:undefined } } </script> <style> </style> 

子组件B内容

<template> <div> <div>componentB</div> </div> </template> <script> export default { 
    name: 'componentB', compnents: { 
   }, data() { 
    return { 
   } } } </script> <style> </style> 

父组件内容

讯享网<template> <div id="box"> <button @click="active='componentA'">componentA</button> <button @click="active='componentB'">componentB</button> <keep-alive> <component :is='active' ></component> </keep-alive> </div> </template> <script> import Vue from 'vue' import componentA from '@/components/componentA' import componentB from '@/components/componentB' export default{ 
    components:{ 
    componentA, componentB }, data(){ 
    return{ 
    active:'componentB' } } } </script> <style> </style> 

输出
在这里插入图片描述

这里看到当A组件被点击激活时就触发activated钩子,点击B组件开启A组件关闭时deactivated钩子就触发执行。

这里也能看出在keep-alive 里A组件的数据也被缓存起来,第二次触发的时候组件状态没有被重新改变

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

1.默认情况下,如果全局的 config.errorHandler定义,所有的错误仍会发送它,因此这些错误仍然会向单一的分析服务的地方进行汇报
如果一个组件的继承或父级从属链路中存在多个 errorCaptured 钩子,则它们将会被相同的错误逐个唤起。
2.如果此 errorCaptured 钩子自身抛出了一个错误,则这个新错误和原本被捕获的错误都会发送给全局的 config.errorHandler,不能捕获异步promise内部抛出的错误和自身的错误
3.一个 errorCaptured 钩子能够返回 false 以阻止错误继续向上传播。本质上是说“这个错误已经被搞定了且应该被忽略”。它会阻止其它任何会被这个错误唤起的 errorCaptured 钩子和全局的 config.errorHandler

在全局组件main.js中使用

import Vue from 'vue'//引入Vue框架 import router from './router'//引入路由 Vue.config.errorHandler = function (err, vm, info) { 
    // #处理错误信息, 进行错误上报 // #err错误对象 // #vm Vue实例 // #`info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子 // #只在 2.2.0+ 可用 console.log("%c%s","color:red","#err错误对象:",err) console.log("%c%s","color:blue","#vm Vue实例:",vm) console.log("%c%s","color:green","#`info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子:",info) } 

然后在子组件中随意写入一个错误的信息

讯享网 mounted () { 
    a // 直接定义一个错误的变量 a }, 

输出
在这里插入图片描述
当这个钩子检测到组件中发生错误时就被调用。通过err, vm, info这3个参数输出
#err错误对象
#vm Vue实例
#info 是 Vue 特定的错误信息,比如错误所在的生命周期钩子

总结一下:

beforecreate:实例刚刚创建出来,data等属性方法都不能获取,loading事件可以放在这里。
created:实例初始化完成,data等属性方法也初始化完成,但还没有开始编译,可以在这里结束loading,可以发送请求,拿数据。!注意一下,因为在这里还没有渲染页面,如果获取的数据过多,会造成有一段空白页面的延迟。
beforemount :属性方法等已经编译完成,但还没挂载。
mounted:这里所有的属性方法已经完成挂载。
beforeUpdate:这个获取的数据是最新的值,但dom还是旧值
updated:dom更新完成。
beforedestroy:消亡前,用来清除定时器
destroy:已消亡,也能用来清除定时器
destroyed:实例完全销毁
activated:可以用来初始化数据
deactivated:在缓存里能用来代替beforedestroy和destroy
errorCaptured :能快速找到报错的组件位置,还能解决满屏红等视觉冲击

问题:

如果当在子组件里写了一个定时器,子组件被销毁后,定时器还是会继续执行,所以要使用beforedestroy和destroyed,组件销毁后,清除定时器。

包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,所以在中的所有组件不会触发beforedestroy 和 destroyed 这两个钩子函数

补充:

在这里插入图片描述

小讯
上一篇 2025-04-03 18:45
下一篇 2025-01-17 19:20

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/51664.html