何为生命周期钩子
官方文档解释:每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码
简单点来说,生命周期就是组件或者实例,从创建到被销毁(初始化化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载)的一系列过程,我们称这是Vue的生命周期
一、 Vue的生命周期阶段
vue生命周期分为四个阶段
- 第一阶段(创建阶段):beforeCreate,created
- 第二阶段(挂载阶段):beforeMount(render),mounted
- 第三阶段(更新阶段):beforeUpdate,updated
- 第四阶段(销毁阶段):beforeDestroy,destroyed
二、 生命周期钩子函数
1. beforeCreate (创建前)
指的是数据监测和数据代理创建之前 , 该钩子函数执行后,初始化数据,并通过Object.defineProperty()和给组件实例配置watcher观察者实例(发布-订阅者模式),实现数据监测与数据代理
在这个阶段,数据是获取不到的,并且真实dom元素也是没有渲染出来的
export default {
data() {
return {
demo: "hello world",
};
},
beforeCreate() {
console.log("beforeCreate执行阶段");
console.log("demo的数据",this.demo);
},
};
打印结果如下:证明此时,data中的数据还未初始化,无法通过Vue实例来访问data中的数据、computed、watch、methods等中的方法。
2. created (创建后)
在这个阶段,可以访问到数据了,但是页面当中真实dom节点还是没有渲染出来,在这个钩子函数里面,可以进行相关初始化事件的绑定、发送请求操作
export default {
data() {
return {
demo: "hello world",
};
},
beforeCreate() {
console.log("beforeCreate执行阶段");
console.log("demo的数据",this.demo);
},
created(){
console.log("created执行阶段");
console.log("demo的数据",this.demo);
}
};
打印结果如下:证明此时,data 数据的初始化完成,数据监测和数据代理创建
3. beforeMount (挂载前)
代表dom马上就要被渲染出来了,但是却还没有真正的渲染出来,这个钩子函数与created钩子函数用法基本一致,可以进行相关初始化事件的绑定、发送ajax操作
beforeMount() 执行时,页面呈现的是未经Vue编译的DOM结构,所有对DOM的操作,最终都不奏效
<div id="app">
<h1 id="box">{{ demo }}</h1>
</div>
export default {
data() {
return {
demo: "hello world",
};
},
beforeMount() {
let box = document.querySelector("#box");
console.log("id名为box的节点",box);
}
};
4. mounted (挂载后)
挂载阶段的最后一个钩子函数,数据挂载完毕,真实dom元素也已经渲染完成了,这个钩子函数内部可以做一些实例化相关的操作
export default {
data() {
return {
demo: "hello world",
};
},
beforeMount() {
console.log("beforeMount执行阶段");
let box = document.querySelector("#box");
console.log("id名为box的节点", box);
},
mounted() {
console.log("mounted执行阶段");
let box = document.querySelector("#box");
console.log("id名为box的节点", box);
},
};
5. beforeUpdate (更新前)
这个钩子函数初始化的不会执行,当组件挂载完毕的时候,并且当数据改变的时候,才会立马执行,这个钩子函数获取dom的内容是更新之前的内容
<div id="app">
<h1 id="box">{{ n }}</h1>
<button @click="update">点击</button>
</div>
export default {
data() {
return {
n: 1,
};
},
methods: {
update() {
this.n += 1;
},
},
beforeUpdate() {
console.log("beforeUpdate执行阶段");
console.log("n的值为", this.n);
},
};
6. updated (更新后)
这个钩子函数获取dom的内容是更新之后的内容生成新的虚拟dom,新的虚拟dom与之前的虚拟dom进行比对,差异之后,就会进行真实dom渲染。在updated钩子函数里面就可以获取到因diff算法比较差异得出来的真实dom渲染了,在这个钩子函数中,页面和数据保持同步
export default {
data() {
return {
n: 1,
};
},
methods: {
update() {
this.n += 1;
},
},
beforeUpdate() {
console.log("beforeUpdate()执行阶段");
console.log("n的值为", this.n);
},
updated(){
console.log("updated执行阶段");
console.log("n的值为", this.n);
}
};
7. beforeDestroy (销毁前)
当组件销毁的时候,就会触发这个钩子函数代表销毁之前,可以做一些善后操作,可以清除一些初始化事件、定时器相关的东西
8. destroyed (销毁后)
实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
vue里很多人几乎不用beforeDestroy和destroyed两个生命周期。但其实很有用
export default {
data() {
return {
timeinter: null,
};
},
mounted() {
this.time();
},
// 销毁实例
beforeDestroy() {
// clearInterval(this.timeinter)
// this.timeinter = null
console.log("组件销毁了");
},
methods: {
// 定时器
time() {
this.timeinter = setInterval(() => {
console.log("定时器");
}, 1000);
},
},
};
组件销毁了定时器还在运行。 我们应该在销毁生命周期了销毁掉这个定时器