人从小到老有一个生命周期,Vue也有自己的生命周期,Vue的生命周期是“一个组件从创建到销毁这个过程就是生命周期”,那么生命周期是怎么判断的呢,人的生命周期是:我们现在的这个阶段,也就是对应着生命周期的某一个阶段,Vue也同样,在特定的时间(阶段)执行特别的事,自动 按次序执行。
生命周期函数(钩子函数)
作用:在特定的时间点,执行某些特定的操作。
Vue生命周期一共分为四个阶段:
- 初始化 => 创建组件 => beforeCreate created
- 挂载 => 渲染显示组件 => beforeMount mouted
- 更新 => 修改了变量 => 触发视图刷新 => beforeUpdate updated
- 销毁 => 切换页面 => 会把组件对象从内存删除 => beforeDestory destoryed
如下图官方文档中所展示的生命周期图
不要急虽然看着很绕很繁琐但是拆分开来看就比较容易,所以现在我们把它拆成几个部分来解读
第一部分
第一个生命周期函数 beforeCreate: 创建前,我写了一段代码进行验证
如果data内有一个值是msg:“我是变量” 那么 beforeCreate 它是拿不到这个值的(methods中的方法也如此),就等于它在实例初始化之前。所以拿出来的就是undefined(未定义)
beforeCreate () {
// 1. 创建前
console.log("beforeCreate --- 实例初始化前")
console.log(this.msg) // 控制台打印 undefined
},
第二个生命周期函数 created :创建后,还是msg来验证,现在这个阶段created是可以拿到msg值的(methods中的方法也如此)可以访问data中定义的值,因为实例已经初始化完成了有值了,所以可以拿到。 再着,created可以发送ajax请求
created () {
// 2. 创建后=> 发送ajax请求
console.log("created --- 实例初始化后")
console.log(this.msg) // 控制台打印 "我是变量"
},
第二部分
图文解析 这个阶段Vue才开始解析模板,生成虚拟DOM,还不能在页面中显示已经解析好了的内容。并查看Vue中是否有“el”若没有“el”到这里就直接结束了,后面的代码不执行。显示的代码也是没有经过解析的。当再次调用vm.$mount……页面就会重新解析,再执行代码。
第三部分
第三个生命周期函数 beforeMount:挂载前: 在挂载开始之前就进行调用,此时还是虚拟DOM,还未真实的展现在页面中,所以此阶段是不能对DOM进行操作的。实验代码如下实验的是页面中的一个ul标签 id名为myUl:
beforeMount() {
// 3. 挂载前
console.log("beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前");
console.log(document.getElementById("myUl")); // 控制台打印 null
// console.log(document.getElementById("myUl").children[1].innerHTML) // 报错
},
第四个生命周期函数 mounted: 挂载后:“el”被vm.$el
替换,并挂载到实例上去之后调用该钩子。如果root 实例挂载了一个文档内元素,当mounted被调用是 vm.$el
也在文档内,此时也是可以对DOM进行操作的,实验代码如下,它是可以拿到这个ul的
mounted() {
// 4. 挂载后=> 操作dom
console.log("mounted --- vue的虚拟DOM, 挂载到真实的网页上 ");
// console.log(document.getElementById("myUl").children[1].innerHTML)
console.log(document.querySelector("#myUl").children[1].innerText);
},
第四部分
图文解析
第五个生命周期函数 beforeUpdate:更新前:数据更新时调用,发生在虚拟DOM打补丁之前,这里适合更新之前访问现有的DOM,比如手动移除已添加的时间监听器,该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行 。
beforeUpdate() {
// 5. 更新前
console.log("beforeUpdate --- 数据更新, 页面更新前");
// 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
// console.log(document.getElementById("myUl").children[4].innerHTML) // 报错
},
第六个生命周期函数 updated:更新后:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 只会在数据变更之后触发这个钩子函数。
updated() {
// 6. 更新后
console.log("updated --- 数据更新, 页面更新后");
console.log(document.getElementById("myUl").children[4].innerHTML);
},
第五部分
第七个生命周期函数 beforeDestroy:销毁前:实例销毁之前调用。在这一步,实例任然完全可用。该钩子在服务器端渲染期间不被调用 实验如下:
beforeDestroy() {
// 7. 销毁前
// (清除定时器 / 解绑js定义的事件)
console.log("beforeDestroy --- 实例销毁之前调用");
},
第八个生命周期函数:销毁后:Vue实例销毁后调用。调用后,Vue实例指示的所有东西,都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用,最主要的作用是可以清楚定时器。 实验如下:
destroyed() {
// 8. 销毁后
// (清除定时器 / 解绑js定义的事件)
console.log("destroyed --- 销毁完成");
},
errorCaptured(2.5.0+ 新增):当捕获一个来自子孙组件的错误时被调用。此钩子会受到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回false以阻止该错误继续向上传播。
最后小结 :
面试常问 有些时候会经常问到以上生命周期执行的顺序以及每个阶段应做的事。还有一点没说到,当页面第一次页面加载时会触发哪几个钩子函数?答:beforeCreate、created、beforeMount、mouted这几个钩子函数
希望这篇文章对正在学Vue的你有所帮助。