每一個(gè)組件或者實(shí)例都會(huì)經(jīng)歷一個(gè)完整的生命周期碟嘴,總共分為三個(gè)階段:初始化鞋既、運(yùn)行中贮配、銷毀谍倦。
官網(wǎng)中生命周期圖示
在生命周期中,總結(jié)了八個(gè)過(guò)程:
實(shí)例泪勒、組件通過(guò)new Vue() 創(chuàng)建出來(lái)之后會(huì)初始化事件和生命周期昼蛀,然后就會(huì)執(zhí)行beforeCreate鉤子函數(shù),這個(gè)時(shí)候圆存,數(shù)據(jù)還沒(méi)有掛載ね叼旋,只是一個(gè)空殼,無(wú)法訪問(wèn)到數(shù)據(jù)和真實(shí)的dom沦辙,一般不做操作
掛載數(shù)據(jù)夫植,綁定事件等等,然后執(zhí)行created函數(shù)油讯,這個(gè)時(shí)候已經(jīng)可以使用到數(shù)據(jù)详民,也可以更改數(shù)據(jù),在這里更改數(shù)據(jù)不會(huì)觸發(fā)updated函數(shù),在這里可以在渲染前倒數(shù)第二次更改數(shù)據(jù)的機(jī)會(huì)陌兑,不會(huì)觸發(fā)其他的鉤子函數(shù)沈跨,一般可以在這里做初始數(shù)據(jù)的獲取
接下來(lái)開始找實(shí)例或者組件對(duì)應(yīng)的模板,編譯模板為虛擬dom放入到render函數(shù)中準(zhǔn)備渲染诀紊,然后執(zhí)行beforeMount鉤子函數(shù)谒出,在這個(gè)函數(shù)中虛擬dom已經(jīng)創(chuàng)建完成,馬上就要渲染,在這里也可以更改數(shù)據(jù)邻奠,不會(huì)觸發(fā)updated笤喳,在這里可以在渲染前最后一次更改數(shù)據(jù)的機(jī)會(huì),不會(huì)觸發(fā)其他的鉤子函數(shù)碌宴,一般可以在這里做初始數(shù)據(jù)的獲取
接下來(lái)開始render杀狡,渲染出真實(shí)dom,然后執(zhí)行mounted鉤子函數(shù)贰镣,此時(shí)呜象,組件已經(jīng)出現(xiàn)在頁(yè)面中,數(shù)據(jù)碑隆、真實(shí)dom都已經(jīng)處理好了,事件都已經(jīng)掛載好了恭陡,可以在這里操作真實(shí)dom等事情...
當(dāng)組件或?qū)嵗臄?shù)據(jù)更改之后,會(huì)立即執(zhí)行beforeUpdate上煤,然后vue的虛擬dom機(jī)制會(huì)重新構(gòu)建虛擬dom與上一次的虛擬dom樹利用diff算法進(jìn)行對(duì)比之后重新渲染休玩,一般不做什么事兒
當(dāng)更新完成后,執(zhí)行updated,數(shù)據(jù)已經(jīng)更改完成拴疤,dom也重新render完成永部,可以操作更新后的虛擬dom
當(dāng)經(jīng)過(guò)某種途徑調(diào)用$destroy方法后,立即執(zhí)行beforeDestroy呐矾,一般在這里做一些善后工作苔埋,例如清除計(jì)時(shí)器、清除非指令綁定的事件等等
組件的數(shù)據(jù)綁定蜒犯、監(jiān)聽...去掉后只剩下dom空殼组橄,這個(gè)時(shí)候,執(zhí)行destroyed愧薛,在這里做善后工作也可以晨炕。
用代碼來(lái)說(shuō)明組件中生命周期的運(yùn)行原理:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" >
</head>
<body>
<div id="app">
<aaa></aaa>
</div>
<template id="aaa">
<div>
<p class="myp">A組件</p>
<button @click="destroy">destroy</button>
<input type="text" v-model="msg">
<p>msg:{{msg}}</p>
</div>
</template>
</body>
<script src="./base/vue.js"></script>
<script>
//生命周期:初始化階段 運(yùn)行中階段 銷毀階段
Vue.component("aaa",{
template:"#aaa",
data:function(){
return {msg:'hello'}
},
timer:null,
methods:{
destroy:function(){
this.$destroy()//
}
},
beforeCreate:function(){
console.log('beforeCreate:剛剛new Vue()之后,這個(gè)時(shí)候毫炉,數(shù)據(jù)還沒(méi)有掛載ね瓮栗,只是一個(gè)空殼')
console.log(this.msg)//undefined
console.log(document.getElementsByClassName("myp")[0])//undefined
},
created:function(){
console.log('created:這個(gè)時(shí)候已經(jīng)可以使用到數(shù)據(jù),也可以更改數(shù)據(jù),在這里更改數(shù)據(jù)不會(huì)觸發(fā)updated函數(shù)')
this.msg+='!!!'
console.log('在這里可以在渲染前倒數(shù)第二次更改數(shù)據(jù)的機(jī)會(huì)瞄勾,不會(huì)觸發(fā)其他的鉤子函數(shù)费奸,一般可以在這里做初始數(shù)據(jù)的獲取')
console.log('接下來(lái)開始找實(shí)例或者組件對(duì)應(yīng)的模板,編譯模板為虛擬dom放入到render函數(shù)中準(zhǔn)備渲染')
},
beforeMount:function(){
console.log('beforeMount:虛擬dom已經(jīng)創(chuàng)建完成进陡,馬上就要渲染,在這里也可以更改數(shù)據(jù)愿阐,不會(huì)觸發(fā)updated')
this.msg+='@@@@'
console.log('在這里可以在渲染前最后一次更改數(shù)據(jù)的機(jī)會(huì),不會(huì)觸發(fā)其他的鉤子函數(shù)趾疚,一般可以在這里做初始數(shù)據(jù)的獲取')
console.log(document.getElementsByClassName("myp")[0])//undefined
console.log('接下來(lái)開始render缨历,渲染出真實(shí)dom')
},
// render:function(createElement){
// console.log('render')
// return createElement('div','hahaha')
// },
mounted:function(){
console.log('mounted:此時(shí),組件已經(jīng)出現(xiàn)在頁(yè)面中糙麦,數(shù)據(jù)辛孵、真實(shí)dom都已經(jīng)處理好了,事件都已經(jīng)掛載好了')
console.log(document.getElementsByClassName("myp")[0])
console.log('可以在這里操作真實(shí)dom等事情...')
this.$options.timer = setInterval(function () {
console.log('setInterval')
this.msg+='!'
}.bind(this),500)
},
beforeUpdate:function(){
console.log('beforeUpdate:重新渲染之前觸發(fā)')
console.log('然后vue的虛擬dom機(jī)制會(huì)重新構(gòu)建虛擬dom與上一次的虛擬dom樹利用diff算法進(jìn)行對(duì)比之后重新渲染')
},
updated:function(){
console.log('updated:數(shù)據(jù)已經(jīng)更改完成,dom也重新render完成')
},
beforeDestroy:function(){
console.log('beforeDestory:銷毀前執(zhí)行($destroy方法被調(diào)用的時(shí)候就會(huì)執(zhí)行),一般在這里擦屁股:清除計(jì)時(shí)器赡磅、清除非指令綁定的事件等等...')
clearInterval(this.$options.timer)
},
destroyed:function(){
console.log('destroyed:組件的數(shù)據(jù)綁定魄缚、監(jiān)聽...都去掉了,只剩下dom空殼')
}
})
new Vue({
}).$mount('#app')
</script>
</html>