生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等,称为Vue实例的生命周期。
一、 使用生命周期钩子
在vue实例的生命周期过程中会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
范例:异步获取列表数据
//模拟异步数据调用接口
function getData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(["萝卜", "白菜"]);
}, 2000);
});
}
const app = new Vue({
//created钩子中调用接口
async created() {
const foodList = await getData();
this.foodList = foodList;
},
});
created 还是mounted?
怎么区分,怎么选择?
created:组件实例已创建,由于未挂载,dom不存在
mounted:
挂载,将渲染函数执行之后得到的虚拟dom,转换为真实dom,这个过程其实是很快的,
可以访问dom元素
异步数据的获取放在created和mounted是没有区别的,
访问数据花销的时间,远远大于初始化挂载的时间,所以没有本质上的区别
二、探讨生命周期
2.1从一道面试题开始
关于Vue的生命周期,下列哪项是不正确的?(B)[单选题]
A、Vue 实例从创建到销毁的过程,就是生命周期。
B、页面首次加载会触发beforeCreate, created, beforeMount, mounted, beforeUpdate,
updated。
C、created表示完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来。
D、DOM渲染在mounted中就已经完成了。
测试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<p>{{title}}</p>
</div>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data() {
return {
title: "hello vue!"
};
},
beforeCreate () {
console.log("beforeCreate")
},
created() {
console.log("created",this.$el)
},
beforeMount () {
console.log("beforeMount")
},
mounted () {
//验证组件更新
setTimeout(()=>{
this.title = "11111111"
},2000);
console.log("mounted",this.$el)
},
beforeUpdate () {
console.log("beforeUpdate")
},
updated () {
console.log("updated")
},
});
</script>
</body>
</html>
2.2生命周期图示
结论:
- 三个阶段:初始化、更新、销毁
- 初始化:beforeCreate、created、beforeMount、mounted
- 更新:beforeUpdate、updated
- 销毁:beforeDestroy、destroyed
2.3使用场景分析
- beforeCreate(){}
执行时组件实例还未创建,通常用于插件开发中执行一些初始化任务- created(){}
组件初始化完毕,各种数据可以使用,常用于异步数据获取- beforeMounted(){}
未执行渲染、更新,dom未创建- mounted(){}
初始化结束,dom已创建,可用于获取访问数据和dom元素
注意 mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick:- beforeUpdate(){}
更新前,可用于获取更新前各种状态
假设一个列表更新了,记录更新之前的滚动条的位置。- updated(){}
更新后,所有状态已是最新
滚动条最新的高度、位置等,都有可能发生变化,这个时候可以做一些更新之后的操作- beforeDestroy(){}
销毁前,可用于一些定时器或订阅的取消
组件实例还在- destroyed(){}
组件已销毁,作用同上
组件实例不在了