什么是生命周期?
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
简单来说,生命周期就是每个Vue实例创建、绑定数据、渲染数据、更新数据、销毁的过程
生命周期的作用
生命周期为我们提供了8个钩子函数,在渲染数据和控制vue实例的时候更方便也容易形成更好的逻辑
生命周期图示
总结执行的顺序就是:beforeCreate --> created --> beforeMount --> mounted --> beforeUpdate --> updated --> beforeDestroy -->destroyed
接下来,我们详细说说每个钩子。
beforeCreate
在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
这时候我们还不能访问实例中的方法和数据,看以下示例就知道了。
在组件Life中定义一个数据name,看在beforeCreate能不能访问的到
export default {
name: "Life",
data(){
return {
name: 'zs'
}
},
beforeCreate() {
console.log('beforeCreate-->',this.name);
}
}
很明显在beforeCreate是访问不到的
created
在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el
property 目前尚不可用。
这个时候我们就可以访问实例中的方法和数据了
具体我们看代码实现
export default {
name: "Life",
data(){
return {
name: 'zs'
}
},
created() {
console.log('created-->',this.name);
}
}
beforeMount
在挂载开始之前被调用:相关的 render
函数首次被调用。
这个时候已经生成html模板,但是数据还没渲染上去
我们怎么验证呢
我们在页面上定义一个p标签,并且把name作为内容
<p>{{name}}</p>
我们在beforeMount中获取这个p标签,并打印出来
beforeMount() {
console.log(document.querySelector('p'));
}
查看下结果
mounted
实例被挂载后调用,这时 el
被新创建的 vm.$el
替换了。如果根实例挂载到了一个文档内的元素上,当 mounted
被调用时 vm.$el
也在文档内。
页面已经完全加载好了,我们可以在这个生命周期中进行网络请求,但是我一般会在created中请求。
注意 mounted
不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted
内部使用 vm.$nextTick:
我们在mounted中执行下beforeMount中的代码查看下结果
mounted() {
console.log(document.querySelector('p'));
}
这个时候已经渲染到页面上了
beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
这时候数据已经更新了,但是页面上的数据还没更新
我们通过定义一个按钮,改变data中的name,来观察下p标签中name有没有变化
<button @click="show">改变</button>
show(){
this.name = 'ls'
}beforeUpdate() {
console.log(this.name);
console.log('beforeUpdate-->',document.querySelector('p').innerText);
}
看下结果
没点击之前
点击之后
对比之后我们发现,虽然数据已经发生改变,但是在beforeupdate中并没有发生变化
updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
数据修改已经完成,而且页面上的数据也已经更新完成
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
在updated中执行beforeupdate中的代码,看下执行结果
beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
beforedestroy是我们最后能访问到组件数据和方法的函数
我们可以通过v-if来模拟销毁组件,在组件中打印下数据和元素
<Life v-if="isshow"></Life>
<button @click="show">删除组件</button>
show(){
this.isshow = false
}
组件内代码:
beforeDestroy() {
console.log(this.name);
console.log('beforeDestroy-->',document.querySelector('p'));
},
当我们点击删除按钮时,打印结果
destroyed
实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
我们同样在destroyed中执行beforedestroy相同代码
destroyed() {
console.log('destroyed-->',document.querySelector('p'));}
这时候已经完全销毁了。
注意点:只有在组件被销毁的时候才会执行这个方法,不管这个方法可不可以访问到实例的数据和方法,都不要在这个生命周期中操作组件中的数据和方法