先來看看vue官網對vue生命週期的介紹
Vue實例有一個完整的生命週期,也就是從開始創建、初始化數據、編譯模板、掛載Dom、渲染→更新→渲染、銷燬等一系列過程,我們稱這是Vue的生命週期。通俗說就是Vue實例從創建到銷燬的過程,就是生命週期。
每一個組件或者實例都會經歷一個完整的生命週期,總共分爲三個階段:初始化、運行中、銷燬。
-
實例、組件通過new Vue() 創建出來之後會初始化事件和生命週期,然後就會執行beforeCreate鉤子函數,這個時候,數據還沒有掛載呢,只是一個空殼,無法訪問到數據和真實的dom,一般不做操作
-
掛載數據,綁定事件等等,然後執行created函數,這個時候已經可以使用到數據,也可以更改數據,在這裏更改數據不會觸發updated函數,在這裏可以在渲染前倒數第二次更改數據的機會,不會觸發其他的鉤子函數,一般可以在這裏做初始數據的獲取
-
接下來開始找實例或者組件對應的模板,編譯模板爲虛擬dom放入到render函數中準備渲染,然後執行beforeMount鉤子函數,在這個函數中虛擬dom已經創建完成,馬上就要渲染,在這裏也可以更改數據,不會觸發updated,在這裏可以在渲染前最後一次更改數據的機會,不會觸發其他的鉤子函數,一般可以在這裏做初始數據的獲取
-
接下來開始render,渲染出真實dom,然後執行mounted鉤子函數,此時,組件已經出現在頁面中,數據、真實dom都已經處理好了,事件都已經掛載好了,可以在這裏操作真實dom等事情...
-
當組件或實例的數據更改之後,會立即執行beforeUpdate,然後vue的虛擬dom機制會重新構建虛擬dom與上一次的虛擬dom樹利用diff算法進行對比之後重新渲染,一般不做什麼事兒
-
當更新完成後,執行updated,數據已經更改完成,dom也重新render完成,可以操作更新後的虛擬dom
-
當經過某種途徑調用$destroy方法後,立即執行beforeDestroy,一般在這裏做一些善後工作,例如清除計時器、清除非指令綁定的事件等等
-
組件的數據綁定、監聽...去掉後只剩下dom空殼,這個時候,執行destroyed,在這裏做善後工作也可以
<!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>
</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="./vue.js"></script>
<script>
//生命週期:初始化階段 運行中階段 銷燬階段
Vue.component("aaa",{
template:"#aaa",
data:function(){
return {msg:'hello'}
},
timer:null,
methods:{
destroy:function(){
this.$destroy()//
}
},
beforeCreate:function(){
console.log('beforeCreate:剛剛new Vue()之後,這個時候,數據還沒有掛載呢,只是一個空殼')
console.log(this.msg)//undefined
console.log(document.getElementsByClassName("myp")[0])//undefined
},
created:function(){
console.log('created:這個時候已經可以使用到數據,也可以更改數據,在這裏更改數據不會觸發updated函數')
this.msg+='!!!'
console.log('在這裏可以在渲染前倒數第二次更改數據的機會,不會觸發其他的鉤子函數,一般可以在這裏做初始數據的獲取')
console.log('接下來開始找實例或者組件對應的模板,編譯模板爲虛擬dom放入到render函數中準備渲染')
},
beforeMount:function(){
console.log('beforeMount:虛擬dom已經創建完成,馬上就要渲染,在這裏也可以更改數據,不會觸發updated')
this.msg+='@@@@'
console.log('在這裏可以在渲染前最後一次更改數據的機會,不會觸發其他的鉤子函數,一般可以在這裏做初始數據的獲取')
console.log(document.getElementsByClassName("myp")[0])//undefined
console.log('接下來開始render,渲染出真實dom')
},
// render:function(createElement){
// console.log('render')
// return createElement('div','hahaha')
// },
mounted:function(){
console.log('mounted:此時,組件已經出現在頁面中,數據、真實dom都已經處理好了,事件都已經掛載好了')
console.log(document.getElementsByClassName("myp")[0])
console.log('可以在這裏操作真實dom等事情...')
// this.$options.timer = setInterval(function () {
// console.log('setInterval')
// this.msg+='!'
// }.bind(this),500)
},
beforeUpdate:function(){
//這裏不能更改數據,否則會陷入死循環
console.log('beforeUpdate:重新渲染之前觸發')
console.log('然後vue的虛擬dom機制會重新構建虛擬dom與上一次的虛擬dom樹利用diff算法進行對比之後重新渲染')
},
updated:function(){
//這裏不能更改數據,否則會陷入死循環
console.log('updated:數據已經更改完成,dom也重新render完成')
},
beforeDestroy:function(){
console.log('beforeDestory:銷燬前執行($destroy方法被調用的時候就會執行),一般在這裏善後:清除計時器、清除非指令綁定的事件等等...')
// clearInterval(this.$options.timer)
},
destroyed:function(){
console.log('destroyed:組件的數據綁定、監聽...都去掉了,只剩下dom空殼,這裏也可以善後')
}
})
new Vue({
}).$mount('#app')
</script>
</html>