一文读懂Vue生命周期(Vue2)
目录
vue生命周期详解,vue更新生命周期,keepalive生命周期,
1 前言
对于一个Vue开发者而言,学习Vue生命周期是必不可少的内容,事实上学习Vue生命周期对于开发高质量的Vue应用至关重要。在初级阶段,需要学习基本组件的生命周期,以了解页面的加载逻辑。而在Vue工程化阶段,就必须要对Vue生命周期有更深的了解。这对以下几个方面来说是基础:
- 理解组件行为:通过了解Vue的生命周期,你可以更深入地理解Vue组件是如何创建、更新和销毁的。这有助于你预测组件在不同阶段的行为,并避免潜在的问题。
- 优化性能:在生命周期的不同阶段,你可以执行特定的操作来优化应用的性能。例如,在
created
阶段,你可以进行数据的初始化或发送网络请求,以避免在模板渲染时产生不必要的延迟。在beforeDestroy
阶段,你可以清除定时器、解绑全局事件或销毁子组件,以防止内存泄漏。 - 更好的状态管理:Vue的生命周期允许你在组件的不同状态下执行特定的逻辑。例如,在
updated
阶段,你可以检查数据的变化并据此更新DOM或触发其他操作。这有助于你更好地管理组件的状态和响应数据的变化。
2 Vue生命周期
学习Vue生命周期是从简单到复杂的循序渐进过程,以下我们把其拆解成三个部分:
- 基本生命周期:单个Vue实例的生命周期;
- 组件生命周期:添加子组件时加载的生命周期;
- keep-alive生命周期:当使用keep-alive包裹组件时,该组件的生命周期;
2.1 基本生命周期
2.1.1 8个生命周期
Vue2基本生命周期钩子函数有11个,主要的生命周期有8个;主要的8个生命周期如下:
- beforeCreate(创建前):在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
- created(创建后):在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,以及 watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
- beforeMount(挂载前):在挂载开始之前被调用:相关的 render 函数首次被调用。此时模板编译已经完成但是还未挂载到页面上。
- mounted(挂载后):el 被新创建的 vm.el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个in−document元素,当mounted被调用时vm.el 也在文档内。此时可以访问到 $el 属性,也可以操作 DOM 和通过 AJAX 获取数据。
- beforeUpdate(更新前):数据更新时调用,发生在虚拟DOM打补丁之前。可以在这个钩子中访问现有的DOM,比如手动移除已添加的事件监听器。
- updated(更新后):由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件DOM已经更新,所以你现在可以执行依赖于DOM的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
- beforeDestroy(销毁前):实例销毁之前调用。在这一步中,实例仍然完全可用。
- destroyed(销毁后):Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑,所有的事件监听器都会被移除,所有的子实例也会被销毁。
官网对8个生命周期图解如下:
2.1.2 案例
仅仅学习理论是不够的,我们来通过案例来看各个生命周期实际执行顺序和各个生命周期能访问得到的内容:
执行顺序:
直接上最简单的能触发所有生命周期代码:
<template>
<div>
<title ref="myPage">生命周期</title>
<div>参数:{
{ parama }}</div>
<el-button @click="updateParama">更新数据</el-button>
<el-button @click="leavePage">离开页面</el-button>
</div>
</template>
<script>
import Vue from "vue";
import {
Button } from "element-ui";
Vue.use(Button);
export default {
beforeCreate() {
console.log("页面加载:beforeCreate");
},
created() {
console.log("页面加载:created");
},
beforeMount() {
console.log("页面加载:beforeMount");
},
mounted() {
console.log("页面加载:mounted");
},
beforeUpdate() {
console.log("页面更新:beforeUpdate");
},
updated() {
console.log("页面更新:updated");
},
beforeDestroy() {
console.log("页面销毁:beforeDestroy");
},
destroyed() {
console.log("页面销毁:destroyed");
},
data() {
return {
parama: 0
};
},
methods: {
leavePage() {
this.$router.push({
path: "/home" });
},
updateParama() {
this.parama++;
}
}
};
</script>
页面效果如下:
当进入该页面时,触发前四个生命周期,执行顺序如控制台打印:
页面加载:beforeCreate
页面加载:created
页面加载:beforeMount
页面加载:mounted
当点击"更新数据"按钮时,依次触发beforeUpdate,updated;控制台打印:
页面更新:beforeUpdate
页面更新:updated
当点击“离开页面”按钮时,依次触发beforeDestroy,destroyed;控制台打印:
页面销毁:beforeDestroy
页面销毁:destroyed
大家可以复制代码自己试一下;
访问数据
再来看各个生命周期页面数据的访问情况,我们在每个生命周期都打印一下数据,代码如下:
beforeCreate() {
console.log("页面加载:beforeCreate");
console.log(this.parama);
},
created() {
console.log("页面加载:created");
console.log(this.parama);
},