03-Vue生命周期

180 阅读3分钟
<!-- vue的生命周期是什么?      
从Vue实例,创建到销毁的过程(一个组件从创建开始经历了数据初始化,挂载,更新等步骤后,最后被销毁)-->
<!-- 如何知道vue生命周期到达那个阶段  使用钩子函数(初始化/挂载/更新/销毁)      
Vue框架内置函数,随着组件的生命周期阶段,自动执行-->    

一 初始化  (创建 => 编译模板) 
Init Events & Lifecycle  ===>  初始化: 生命周期, 事件 , 但数据代理还未开始    
// new Vue()以后,vue内部给实例对象添加了一些属性和方法, data和methods初始化之前   
beforeCreate(){  //创建前状态        
    console.log(this.$el); //undefined        
    console.log(this.$data); //undefined
},  
Init injections $ reactivity  ===> 初始化:  数据监测 数据代理
// data和methods初始化以后  使用场景:网络请求 ,注册全局事件 
created(){  //创建完毕状态 , 能获取data,不能获取真实DOM        
    console.log(this.$el);  //undefined        
    console.log(this.$data); //{__ob__: Observer}
},  

// 编译模板阶段   ===>  此阶段Vue开始解析模板, 生成虚拟DOM(内存中), 页面还不能显示解析好的内容
Has "el" option ?
// 是否有el选项 -检查要挂到哪里(容器)   
// 没有 当调用vm.$mount()方法之后再继续执行  ||  有 继续检查template选项    

// template 选项检查(模板)     
Has "template" option ?
// 有-编译template进入render渲染函数 || 无 -编译el选项对应标签作为要渲染的模板  
  
二 挂载  (创建 => 显示)    
// 虚拟DOM挂载为真实DOM挂载之前  使用场景 :预处理data ,不会触发updated钩子函数   
beforeMount(){    ===>   此时: 页面呈现的是未经Vue编译的DOM解构, 所有对DOM的操作, 最终都不生效      
    console.log(this.$el);  //undefined
},    
Create vm.$el and replace "el" with it  =>   将内存中的虚拟DOM , 转换为真实DOM 插入页面
// 真实DOM挂载以后 使用场景 :挂载后真实DOM    
mounted() {      ===>   此时:  页面呈现的是经过Vue编译的DOM, 对DOM的操作均有效(尽可能避免),
                    初始化过程结束, 一般在此时:开启定时器, 发送网络请求, 等初始化操作
    console.log(this.$el); //<div></div>    
},   
 

三 更新  前提是data数据改变才会执行    
// 更新之前    
beforeUpdate(){ 
       //此时: 数据是新的,但页面是旧的 , 即: 页面尚未和数据保持同步!!!
},    
Vitual DOM re-render and patch ===> 根据新数据,生成新的虚拟DOM,随后与旧虚拟DOM进行比较,
                                    最终完成页面的更新, 即: 完成了Model -> View 的更新
// 更新之后  使用场景 :获取更新后的真实DOM    
updated(){
        //此时: 页面和数据保持同步
},    

四 销毁组件  前提是当$destroy()被调用      
// 比如组件DOM被移除(v-if="false") 销毁vue实例    
beforeDestroy(){ 
   // 此时: vm中的data,methods ,指令都处于可用状态, 马上要执行销毁过程, 操作数据页面也不会再更新
   //一般再次阶段: 移除全局事件 ,拆卸数据监视器,子组件,定时器,eventBus移除事件$off方法等收尾操作   
   },    
Teardown watchers,child components and event listeners(自定义事件)
// 实例销毁后执行    
destroyed(){    },

1、Vue 的 nextTick 的原理是什么? (高薪常问)

​ \1. 为什么需要 nextTick ,Vue 是异步修改 DOM 的并且不鼓励开发者直接接触 DOM,但有时候业务需要必须对数据更改--刷新后的 DOM 做相应的处理,这时候就可以使用 Vue.nextTick(callback)这个 api 了。

​ \2. 理解原理前的准备 首先需要知道事件循环中宏任务和微任务这两个概念,常见的宏任务有 script, setTimeout, setInterval, setImmediate, I/O, UI rendering 常见的微任务有 process.nextTick(Nodejs),Promise.then(), MutationObserver;

​ \3. 理解 nextTick 的原理正是 vue 通过异步队列控制 DOM 更新和 nextTick 回调函数先后执行的方式。如果大家看过这部分的源码,会发现其中做了很多 isNative()的判断,因为这里还存在兼容性优雅降级的问题。可见 Vue 开发团队的深思熟虑,对性能的良苦用心。

2、vue生命周期总共分为几个阶段?(必会)

Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

1**)beforeCreate**

​ 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

2**)created**

​ 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer), 属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

3**)beforeMount**

​ 在挂载开始之前被调用:相关的 render 函数首次被调用。

4**)mounted**

​ el 被新创建的 vm.​el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

5**)beforeUpdate**

​数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。

6**)updated**

​ 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

7**)activated**

​ keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用。

8**)deactivated**

​ keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用。

9**)beforeDestroy**

​ 实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。

10**)destroyed**

​ Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

11**)errorCaptured(2.5.0+ 新增)**

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

3、第一次加载页面会触发哪几个钩子函数?(必会)

当页面第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子函数