首先昂利,每個(gè)Vue實(shí)例在被創(chuàng)建之前都要經(jīng)過(guò)一系列的初始化過(guò)程,這個(gè)過(guò)程就是vue的生命周期辑奈。首先看一張圖吧~這是官方文檔上的圖片相信大家一定都會(huì)很熟悉:
可以看到在vue一整個(gè)的生命周期中會(huì)有很多鉤子函數(shù)提供給我們?cè)趘ue生命周期不同的時(shí)刻進(jìn)行操作, 那么先列出所有的鉤子函數(shù),然后我們?cè)僖灰辉斀?
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
先來(lái)一波ctrl+c,各位ctrl+v在瀏覽器中運(yùn)行,打開(kāi)console查看就行了:
<!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>vue生命周期學(xué)習(xí)</title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Vue的生命周期'
},
beforeCreate: function() {
console.group('------beforeCreate創(chuàng)建前狀態(tài)------');
console.log("%c%s", "color:red" , "el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //undefined
console.log("%c%s", "color:red","message: " + this.message)
},
created: function() {
console.group('------created創(chuàng)建完畢狀態(tài)------');
console.log("%c%s", "color:red","el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeMount: function() {
console.group('------beforeMount掛載前狀態(tài)------');
console.log("%c%s", "color:red","el : " + (this.$el)); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
mounted: function() {
console.group('------mounted 掛載結(jié)束狀態(tài)------');
console.log("%c%s", "color:red","el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeUpdate: function () {
console.group('beforeUpdate 更新前狀態(tài)===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
updated: function () {
console.group('updated 更新完成狀態(tài)===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
beforeDestroy: function () {
console.group('beforeDestroy 銷毀前狀態(tài)===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
destroyed: function () {
console.group('destroyed 銷毀完成狀態(tài)===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message)
}
})
</script>
</html>
運(yùn)行后打開(kāi)console可以看到打印出來(lái)內(nèi)容如下:
可以看到一個(gè)vue實(shí)例在創(chuàng)建過(guò)程中調(diào)用的幾個(gè)生命周期鉤子。
在beforeCreate和created鉤子函數(shù)之間的生命周期
在這個(gè)生命周期之間抡柿,進(jìn)行初始化事件,進(jìn)行數(shù)據(jù)的觀測(cè)等恐,可以看到在created的時(shí)候數(shù)據(jù)已經(jīng)和data屬性進(jìn)行綁定(放在data中的屬性當(dāng)值發(fā)生改變的同時(shí)洲劣,視圖也會(huì)改變)。
注意看下:此時(shí)還是沒(méi)有el選項(xiàng)created鉤子函數(shù)和beforeMount間的生命周期
[圖片上傳中...(image.png-eab2c1-1553501663335-0)]
在這一階段發(fā)生的事情還是比較多的课蔬。
首先會(huì)判斷對(duì)象是否有el選項(xiàng)囱稽。如果有的話就繼續(xù)向下編譯,如果沒(méi)有el選項(xiàng)二跋,則停止編譯战惊,也就意味著停止了生命周期,直到在該vue實(shí)例上調(diào)用vm.$mount(el)扎即。此時(shí)注釋掉代碼中:
el: '#app',
然后運(yùn)行可以看到到created的時(shí)候就停止了:
如果我們?cè)诤竺胬^續(xù)調(diào)用vm.$mount(el),可以發(fā)現(xiàn)代碼繼續(xù)向下執(zhí)行了
vm.$mount(el) //這個(gè)el參數(shù)就是掛在的dom接點(diǎn)
然后吞获,我們往下看况凉,template參數(shù)選項(xiàng)的有無(wú)對(duì)生命周期的影響。
(1).如果vue實(shí)例對(duì)象中有template參數(shù)選項(xiàng)各拷,則將其作為模板編譯成render函數(shù)刁绒。
(2).如果沒(méi)有template選項(xiàng),則將外部HTML作為模板編譯烤黍。
(3).可以看到template中的模板優(yōu)先級(jí)要高于outer HTML的優(yōu)先級(jí)知市。
修改代碼如下, 在HTML結(jié)構(gòu)中增加了一串html,在vue對(duì)象中增加了template選項(xiàng):
<!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>vue生命周期學(xué)習(xí)</title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
</head>
<body>
<div id="app">
<!--html中修改的-->
<h1>{{message + '這是在outer HTML中的'}}</h1>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
template: "<h1>{{message +'這是在template中的'}}</h1>", //在vue配置項(xiàng)中修改的
data: {
message: 'Vue的生命周期'
}
</script>
</html>
執(zhí)行后的結(jié)果可以看到在頁(yè)面中顯示的是:
那么將vue對(duì)象中template的選項(xiàng)注釋掉后打印如下信息:
這下就可以想想什么el的判斷要在template之前了~是因?yàn)関ue需要通過(guò)el找到對(duì)應(yīng)的outer template蚊荣。
在vue對(duì)象中還有一個(gè)render函數(shù)初狰,它是以createElement作為參數(shù)莫杈,然后做渲染操作互例,而且我們可以直接嵌入JSX.
new Vue({
el: '#app',
render: function(createElement) {
return createElement('h1', 'this is createElement')
}
})
可以看到頁(yè)面中渲染的是:
所以綜合排名優(yōu)先級(jí):
render函數(shù)選項(xiàng) > template選項(xiàng) > outer HTML.
-
beforeMount和mounted 鉤子函數(shù)間的生命周期
可以看到此時(shí)是給vue實(shí)例對(duì)象添加$el成員,并且替換掉掛在的DOM元素筝闹。因?yàn)樵谥癱onsole中打印的結(jié)果可以看到beforeMount之前el上還是undefined媳叨。
-
mounted
注意看下面截圖:
在mounted之前h1中還是通過(guò){{message}}進(jìn)行占位的,因?yàn)榇藭r(shí)還有掛在到頁(yè)面上关顷,還是JavaScript中的虛擬DOM形式存在的糊秆。在mounted之后可以看到h1中的內(nèi)容發(fā)生了變化。
-
beforeUpdate鉤子函數(shù)和updated鉤子函數(shù)間的生命周期
當(dāng)vue發(fā)現(xiàn)data中的數(shù)據(jù)發(fā)生了改變议双,會(huì)觸發(fā)對(duì)應(yīng)組件的重新渲染痘番,先后調(diào)用beforeUpdate和updated鉤子函數(shù)。我們?cè)赾onsole中輸入:
vm.message = '觸發(fā)組件更新'
發(fā)現(xiàn)觸發(fā)了組件的更新:
6.beforeDestroy和destroyed鉤子函數(shù)間的生命周期
beforeDestroy鉤子函數(shù)在實(shí)例銷毀之前調(diào)用平痰。在這一步汞舱,實(shí)例仍然完全可用。
destroyed鉤子函數(shù)在Vue 實(shí)例銷毀后調(diào)用宗雇。調(diào)用后昂芜,Vue 實(shí)例指示的所有東西都會(huì)解綁定,所有的事件監(jiān)聽(tīng)器會(huì)被移除赔蒲,所有的子實(shí)例也會(huì)被銷毀泌神。
本文是個(gè)人對(duì)vue的生命周期的理解,有什么不對(duì)的地方還請(qǐng)大神多多指點(diǎn)~