后边是有案例的,通过案例依次分析Vue生命周期所包含的4大阶段,8大钩子函数。
1.vue生命周期是什么?
Vue生命周期是指vue实例对象从创建之初到销毁的过程,vue所有功能的实现都是围绕其生命周期进行的,在生命周期的不同阶段调用对应的钩子函数实现组件数据管理和DOM渲染两大重要功能。
2.vue生命周期可以分为八个阶段。
1、创建前(beforeCreate)
对应的钩子函数为beforeCreate。此阶段为实例初始化之后,此时的数据观察和事件机制都未形成,不能获得DOM节点。
vue实例中的el,data,data中的属性都为undefined (详见案例)
2、创建后(created)
对应的钩子函数为created。在这个阶段vue实例已经创建,仍然不能获取DOM元素。
el依旧是undefined,而数据已经与data中的属性进行绑定(放在data中属性当值发生改变的同时,视图也会发生变化),在这里可以在渲染前倒数第二次更改数据的机会(最后一次更改是下一个钩子函数),可以在这里做初始数据的获取(详见案例)
3、载入前(beforeMount)
对应的钩子函数是beforeMount,在这一阶段,依然得不到具体的DOM元素,但vue挂载的根节点已经创建,下面vue对DOM的操作将围绕这个根元素继续进行;beforeMount这个阶段是过渡性的,一般一个项目只能用到一两次。
载入前(完成了data和el数据初始化),但是页面中的内容还是vue中的占位符,data中的message信息没有被挂在到DOM节点中,在这里是渲染前最后一次更改数据的机会了,不会触发其他的钩子函数,可以在这里做初始数据的获取(详见案例)
4、载入后(mounted)
created不能操作DOM节点,mounted可以操作DOM节点
对应的钩子函数是mounted。mounted是平时我们使用最多的函数了,一般我们的异步请求都写在这里。在这个阶段,数据和DOM都已被渲染出来。
载入后html已经渲染(ajax请求可以放在这个函数中),把vue实例中的data里的message挂载到BOM节点中去
5、更新前(beforeUpdate)
对应的钩子函数是beforeUpdate。在这一阶段,vue遵循数据驱动DOM的原则;beforeUpdate函数在数据更新后虽然没立即更新数据,但是DOM中的数据会改变,这是Vue双向数据绑定的作用。
更新前状态(view层的数据变化前,不是data中的数据改变前),重新渲染之前触发,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树进行对比之后重新渲染(详见效果2)
6、更新后(updated)
对应的钩子函数是updated。在这一阶段DOM会和更改过的内容同步。
数据已经更改完成,dom也重新渲染完成(详见效果2)
7、销毁前(beforeDestroy)
对应的钩子函数是beforeDestroy。在上一阶段vue已经成功的通过数据驱动DOM更新,当我们不在需要vue操纵DOM时,就需要销毁Vue,也就是清除vue实例与DOM的关联,调用destroy方法可以销毁当前组件。在销毁前,会触发beforeDestroy钩子函数。
销毁前执行($destroy方法被调用的时候就会执行),一般在这里善后:清除计时器、清除非指令绑定的事件等等…’)(详见效果3)
8、销毁后(destroyed)
对应的钩子函数是destroyed。在销毁后,会触发destroyed钩子函数。
销毁后 (Dom元素存在,只是不再受vue控制),卸载watcher,事件监听,子组件(详见效果3)
代码:
配置路由:页面重定向为index,跳转到content组件,再从content组件跳转到last组件,完成content组件的一整个生命周期。
import Vue from 'vue'
import Router from 'vue-router'
import Index from "@/sszq-pages/Index.vue"
import Content from "@/sszq-pages/Content.vue"
import Last from "@/sszq-pages/Last.vue"
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
redirect:'/index',
},
{
path: '/index',
name: 'index',
component:Index
},
{
path: '/content',
name: 'content',
component:Content
},
{
path: '/last',
name: 'last',
component:Last
}
]
})
index组件:
<template>
<div>
<p>Hello World!</p>
<router-link to="/content">点击跳转content</router-link>
</div>
</template>
<script>
import contents from "@/sszq-pages/Content.vue"
export default {
name: 'index',
components: {
contents
},
data () {
return {
}
}
}
</script>
content组件:
<template>
<div>
<p>{{msg}}</p>
<button @click="toChange()">更改数据</button>
<router-link to="/last">销毁此组件,跳转新界面</router-link>
</div>
</template>
<script>
import Last from "@/sszq-pages/Last.vue"
export default {
name: 'last',
components: {
Last
},
data () {
return {
msg:'这是初始数据'
}
},
beforeCreate() {
console.log('this.$el 值为',this.$el,'创建前')
console.log('this.msg 值为',this.msg,'创建前')
},
created() {
console.log('this.$el 值为',this.$el,'创建后')
console.log('this.msg 值为',this.msg,'创建后')
},
beforeMount() {
console.log('this.$el 值为',this.$el,'载入前')
console.log('this.msg 值为',this.msg,'载入前')
},
mounted() {
console.log('this.$el 值为',this.$el,'载入后')
console.log('this.msg 值为',this.msg,'载入后')
},
beforeUpdate() {
alert('页面数据即将改变。')
console.log('this.$el 值为',this.$el,'更新前')
console.log('this.msg 值为',this.msg,'更新前')
alert('页面数据已经改变。')
},
updated() {
alert('执行更新后。')
console.log('this.$el 值为',this.$el,'更新后')
console.log('this.msg 值为',this.msg,'更新后')
},
beforeDestroy() {
console.log('this.$el 值为',this.$el,'销毁前')
console.log('this.msg 值为',this.msg,'销毁前')
alert('销毁该组件?')
},
destroyed() {
console.log('this.$el 值为',this.$el,'销毁后')
console.log('this.msg 值为',this.msg,'销毁后')
},
methods:{
toChange(){
this.msg='我是新的数据'
}
}
}
</script>
Last组件:
<template>
<div>
<p>这是last</p>
</div>
</template>
<script>
export default {
name: 'Last',
data () {
return {
}
},
}
</script>
效果1:第一次加载页面会触发 beforeCreate, created, beforeMount, mounted 四个钩子。
效果2: (beforeUpdate updated)
效果3:(beforeDestroy destroyed)
3.生命周期适用场景
beforecreate : 可以在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也可以在这里调用
mounted : 可以在这里向后端发送请求,获取数据,挂载元素,获取到DOM节点。
updated : 如果对数据统一处理,在这里写上相应函数
beforeDestroy : 可以做一个确认停止事件的确认框 nextTick : 更新数据后立即操作dom
4.对vue生命周期的理解
创建前/后:在beforeCreated阶段,vue实例的挂载完el还没有。
载入前/后:在beforeMount阶段,vue实例的$el和data都已经初始化,但还是挂载之前为虚拟的dom节点,案例中的data.msg还未替换。在mounted阶段,vue实例挂载完成,data.msg成功渲染。
更新前/后:当data变化时,会触发beforeUpdate和updated方法。
销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,DOM元素存在,只是不再受vue的控制。
后续会继续完善~~