生命周期:一个组件从创建到销毁的一系列过程就叫做这个组件的生命周期。
每一个组件或者实例都会经历一个完整的生命周期,一个生命周期总共分为三个阶段,其中又共包含了八种生命周期钩子函数:
初始阶段:beforeCreate ; created ; beforeMount ; mounted
运行阶段:beforeUpdate ; updated
销毁阶段: beforeDestroy ; destroyed
如下列的生命周期图:
1.beforeCreate 这个钩子函数在创建组件初始化的时候会立刻执行,并且在这个钩子函数里是获取不到数据的,而此时页面中的真实dom节点为null,没有挂在出来。
2.created 这个钩子函数内部的数据已经挂载了,但真实dom节点也还是没有渲染出来,通常会在这个钩子函数里面进行ajax的异步操作。
3.beforeMount 是让组件或者实列去查找各自的模板,而后将其编译成虚拟dom,即将放入render函数中做初始化渲染操作。
4.mounted 这是初始化阶段的最后一个钩子函数,数据挂在完成,真实的dom已经渲染出来了。
5.beforeUpdate 这个钩子函数只有当dom挂载完成,并且进行数据的更新时,才会被执行。
6.updated 这个钩子函数里dom获取的数据内容是更新后的数据内容。
7.beforeDestroy 组件销毁时触发,在销毁前可以清楚一些事件绑定。
8.destroyed 组件销毁时触发,vue实例解除了事件监听以及和dom的绑定(无响应了),但DOM节点依旧是存在的
下面是一个swiper轮播图案列:
注:因为这个案例主要是便于让我们更好的去理解生命周期,所以只有部分(主要)代码,只要知道我们遇到生命周期什么问题,怎么解决就可以了,下面会说到
创建结构模板的代码:
<div id="box">
<my-banner></my-banner>
</div>
<template id="my-banner">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="banner in banners">
<img width="100%" :src="banner.image" alt="">
</div>
</div>
</div>
</template>
JS代码:
Vue.component("my-banner",{
template:"#my-banner",
data(){
return {
banners:[]
}
},
created(){
this.$http.get("./banners.json").then(res=>{
console.log(res.data.bannerList)
this.banners = res.data.bannerList
new Swiper(".swiper-container",{
loop:true
})
})
}
})
如果向上面这样写的话,就会出现bug——轮播图划动不了
原因:当划动图片的时候,相当于改变了数据,而当更改完数据后会立即进行实例化操作,等虚拟dom更新完成后生成真实的dom结构,其实实例化操作已经提前结束完毕了。
解决:页面当中的swiper-slide真实dom全都渲染完毕了,再去进行swiper的实例化操作,也就是把new Swiper(".swiper-container",{loop:true })放到最后操作
下面例举了哪种钩子函数能够解决成功:
beforeMount 钩子函数不能解决,因为这个时候真实的dom还没有渲染出来,这个钩子函数获取不到真实dom的结构。
created(){
this.$http.get("./banners.json").then(res=>{
console.log(res.data.bannerList)
this.banners = res.data.bannerList
})
},
beforeMount(){
new Swiper(".swiper-container",{
loop:true
})
}
mounted 钩子函数也不能解决,因为上面是异步的过程,他不会阻止后续mounted的相关操作。内部的异步请求边去进行请求数据的同时,下面的mounted钩子函数也正在执行,当数据回来进行进行更改操作,其实这个实例化操作早就结束了
created(){
this.$http.get("./banners.json").then(res=>{
console.log(res.data.bannerList)
this.banners = res.data.bannerList
})
},
mounted(){
new Swiper(".swiper-container",{
loop:true
})
}
beforeUpdate 这个钩子函数里面也不可以,因为当dom挂载完毕的时候,当数据发生改变的时候,他会立马执行!
created() {
this.$http.get("./banners.json").then(res => {
console.log(res.data.bannerList)
this.banners = res.data.bannerList
})
},
beforeUpdate(){
new Swiper(".swiper-container",{
loop:true
})
}
updated 这个钩子函数是可以的,当数据发生改变的时候,引发虚拟dom的对比,虚拟dom对比完成后,再去渲染真实的dom结构当真实的dom结构渲染完成后,内部才会执行updated钩子函数
created() {
this.$http.get("./banners.json").then(res => {
console.log(res.data.bannerList)
this.banners = res.data.bannerList
})
},
updated(){
new Swiper(".swiper-container",{
loop:true
})
}
最后理解了vue的生命周期钩子函数的执行,我们就知道在哪个阶段,我们可以做些什么了