<!-- 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 这几个钩子函数