對(duì)vue生命周期的深入理解
一.Vue生命周期簡(jiǎn)介
官網(wǎng):https://cn.vuejs.org/v2/api/#beforeCreate
Vue實(shí)例從創(chuàng)建到銷(xiāo)毀的過(guò)程,就是生命周期。詳細(xì)來(lái)說(shuō)也就是從開(kāi)始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom、渲染→更新→渲染、卸載等一系列過(guò)程。
首先我們來(lái)看一下官網(wǎng)的生命周期圖(我自己做了一點(diǎn)點(diǎn)注釋?zhuān)?/p>
Vue提供給我們的鉤子為上圖的紅色的文字
二.鉤子詳解
1.beforeCreate
在實(shí)例初始化之后,數(shù)據(jù)觀測(cè)(data observer) 和 event/watcher 事件配置之前被調(diào)用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<!-- 引入vue.js -->
<script type="text/javascript" src='./vue.js'></script>
</head>
<body>
<div id="app">
<input type="text" name="" v-model="message">
{{message}}
</div>
<script type="text/javascript">
//實(shí)例化Vue
var app = new Vue({
el:'#app',
data:{
message:'this is mseeage'
},
//時(shí)刻監(jiān)測(cè)數(shù)據(jù)message的變化,一但那變化就會(huì)吊該函數(shù)
watch:{
//message必須和監(jiān)測(cè)的data名字一樣
message:function(){
console.log('watch:','message 變了')
}
},
methods:{
init:function(){
console.log('這是初始化方法')
}
},
//我們?cè)赽eforeCreate鉤子中調(diào)用Vue的data和method
beforeCreate:function(){
console.log("beforeCreate",this.message);
this.init();
}
})
</script>
</body>
</html>
我們?cè)谏厦娴睦又性诘腷eforeCreate鉤子中調(diào)用Vue的data和method,來(lái)看一下結(jié)果:
可以看到Vue中的data和方法都是去不到的,并且是在wath之前執(zhí)行
2.created
實(shí)例已經(jīng)創(chuàng)建完成之后被調(diào)用。在這一步,實(shí)例已完成以下的配置:數(shù)據(jù)觀測(cè)(data observer),屬性和方法的運(yùn)算, watch/event 事件回調(diào)。然而,掛載階段還沒(méi)開(kāi)始,$el 屬性目前不可見(jiàn)。
主要應(yīng)用:調(diào)用數(shù)據(jù),調(diào)用方法,調(diào)用異步函數(shù)
<div id="app">
<ul>
<li v-for="(item,index) of list" key="index">{{item}}--{{message}}</li>
</ul>
<p>p1</p>
<p>p1</p>
<p>p1</p>
</div>
<script type="text/javascript">
//實(shí)例化Vue
var app = new Vue({
el:'#app',
data:{
message:'this is mseeage',
list:['aaaaaaaa','bbbbbbb','ccccccc']
},
//時(shí)刻監(jiān)測(cè)數(shù)據(jù)message的變化,一但那變化就會(huì)吊該函數(shù)
watch:{
//message必須和監(jiān)測(cè)的data名字一樣
message:function(){
console.log('watch:','message 變了')
}
},
methods:{
foo:function(){
console.log('foo : ','這是初始化方法')
}
},
//created鉤子
created:function(){
//調(diào)用Vue的data
console.log("created : ",this.message);
//調(diào)用Vue方法
this.foo();
//因?yàn)槲覀兪峭ㄟ^(guò)v-for循環(huán)遍歷li,所以created之前掛載階段還沒(méi)開(kāi)始.是無(wú)法獲取li的個(gè)數(shù)的
console.log('li數(shù)量:',document.getElementsByTagName('li').length);
//直接加載出來(lái)的DOM是可以直接獲取到的
console.log('p個(gè)數(shù):',document.getElementsByTagName('p').length);
},
})
</script>
結(jié)果:
可以看到:created鉤子可以獲取Vue的data,調(diào)用Vue方法,獲取原本HTML上的直接加載出來(lái)的DOM,但是無(wú)法獲取到通過(guò)掛載模板生成的DOM(例如:v-for循環(huán)遍歷Vue.list生成li)
3.beforeMount
在掛載開(kāi)始之前被調(diào)用:相關(guān)的 render 函數(shù)(模板)首次被調(diào)用。
例如通過(guò)v-for生成的html還沒(méi)有被掛載到頁(yè)面上
(接 2created的代碼)
beforeMount: function () {
console.log('beforeMount:',document.getElementsByTagName('li').length);
},
結(jié)果 beforeMount: 1
4.mounted
el 被新創(chuàng)建的 vm.$el 替換,并掛載到實(shí)例上去之后調(diào)用該鉤子。
有初始值的DOM渲染,例如我們的初始數(shù)據(jù)list,渲染出來(lái)的li,只有這里才能獲取
(接 2created的代碼)
mounted: function () {
console.log('mounted:',document.getElementsByTagName('li').length);
},
結(jié)果 mounted: 3
可以看到到這里為止,掛載到實(shí)例上了,我們可以獲取到li的個(gè)數(shù)了
5.beforeUpdate
數(shù)據(jù)更新時(shí)調(diào)用,發(fā)生在虛擬 DOM 重新渲染和打補(bǔ)丁之前。 你可以在這個(gè)鉤子中進(jìn)一步地更改狀態(tài),這不會(huì)觸發(fā)附加的重渲染過(guò)程。
當(dāng)我們更改Vue的任何數(shù)據(jù),都會(huì)觸發(fā)該函數(shù)
beforeUpdate: function () {
console.log('beforeUpdate 鉤子執(zhí)行...');
console.log('beforeUpdate:'+this.message)
},
6.updated
由于數(shù)據(jù)更改導(dǎo)致的虛擬 DOM 重新渲染和打補(bǔ)丁,在這之后會(huì)調(diào)用該鉤子。
當(dāng)這個(gè)鉤子被調(diào)用時(shí),組件 DOM 已經(jīng)更新,所以你現(xiàn)在可以執(zhí)行依賴(lài)于 DOM 的操作。然而在大多數(shù)情況下,你應(yīng)該避免在此期間更改狀態(tài),因?yàn)檫@可能會(huì)導(dǎo)致更新無(wú)限循環(huán)。
該鉤子在服務(wù)器端渲染期間不被調(diào)用。
數(shù)據(jù)更新就會(huì)觸發(fā)(vue所有的數(shù)據(jù)只有有更新就會(huì)觸發(fā)),如果想數(shù)據(jù)一遍就做統(tǒng)一的處理,可以用這個(gè),如果想對(duì)不同數(shù)據(jù)的更新做不同的處理可以用nextTick,或者是watch進(jìn)行監(jiān)聽(tīng)
updated: function () {
console.log('updated 鉤子執(zhí)行...');
console.log('updated:',this.message)
},
7.beforeDestroy
實(shí)例銷(xiāo)毀之前調(diào)用。在這一步,實(shí)例仍然完全可用。
8.destroyed
Vue 實(shí)例銷(xiāo)毀后調(diào)用。調(diào)用后,Vue 實(shí)例指示的所有東西都會(huì)解綁定,所有的事件監(jiān)聽(tīng)器會(huì)被移除,所有的子實(shí)例也會(huì)被銷(xiāo)毀。 該鉤子在服務(wù)器端渲染期間不被調(diào)用。
<div id="app">
</div>
<script type="text/javascript">
//實(shí)例化Vue
var app = new Vue({
el:'#app',
data:{
message:'this is mseeage',
},
beforeDestroy: function () {
console.log('beforeDestroy 鉤子執(zhí)行...',this.message)
},
destroyed: function () {
console.log('destroyed 鉤子執(zhí)行...',this.message)
}
})
//銷(xiāo)毀Vue實(shí)例,觸發(fā)beforeDestroy和destroyed函數(shù)
app.$destroy()
</script>
結(jié)果:
可以看打到銷(xiāo)毀Vue實(shí)例時(shí)會(huì)調(diào)用這兩個(gè)函數(shù)
補(bǔ)充$mount
當(dāng)你vue沒(méi)有掛在el時(shí),我們可以用$mount
var app = new Vue({
data:{
message:'this is mseeage',
},
}).$mount('#app')
三.鉤子的一些實(shí)戰(zhàn)用法
1.異步函數(shù)
這里我們用定時(shí)器來(lái)做異步函數(shù)
<div id="app">
<ul>
<li v-for="(item,index) of list" key="index">{{item}}</li>
</ul>
</div>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
list:['aaaaaaaa','bbbbbbb','ccccccc']
},
created:function(){
consoloe.log('created異步:aaaaa');
//異步獲取數(shù)據(jù)
// 因?yàn)槭钱惒?就和我們ajax獲取數(shù)據(jù)一樣
setTimeout(()=>{
this.list=['111','222','333','444'],
console.log('created異步:',document.getElementsByTagName('li').length);
},0)
},
mounted: function () {
console.log('mounted:',document.getElementsByTagName('li').length);
},
updated: function () {
console.log('updated:',document.getElementsByTagName('li').length)
},
})
</script>
結(jié)果為:
create: aaaaaaaa
mounted: 3
created異步函數(shù): 3
updated: 4
解釋?zhuān)?/strong>
可以看到因?yàn)槭窃赾reated的鉤子中加入異步函數(shù),所以函數(shù)的執(zhí)行順序?yàn)椋?/p>
ceated鉤子,mounted鉤子,異步函數(shù),updated鉤子(根據(jù)事件隊(duì)列原理,只有在updated后,li才是真的DOM渲染為4個(gè),所以異步函數(shù)中獲取的li的個(gè)數(shù)時(shí)是沒(méi)有變化的li的個(gè)數(shù))。
因?yàn)閙ounted獲取到的是我們?cè)赩ue的data中設(shè)置初始值渲染的DOM,而我們是在異步函數(shù)中變化的list數(shù)據(jù),所以mounted獲取的li的個(gè)數(shù)為3。
update函數(shù)是只要數(shù)據(jù)vue綁定的數(shù)據(jù)變化就會(huì)觸發(fā),所以最后執(zhí)行,為4
這是不是意味著可以直接在update函數(shù)中操作呢,其實(shí)不是,因?yàn)閡pdate函數(shù)是針對(duì)vue的所有數(shù)據(jù)的變化,而我們也有可能會(huì)有其他數(shù)據(jù)的變化。
例如下面的例子:
//我們利用異步函數(shù)改變了兩次list,會(huì)發(fā)現(xiàn)update被觸發(fā)了2次
created:function(){
//異步獲取數(shù)據(jù)
// 因?yàn)槭钱惒?就和我們ajax獲取數(shù)據(jù)一樣
setTimeout(()=>{
this.list=['111','222','333','444'],
console.log('created異步:',document.getElementsByTagName('li').length);
},0)
setTimeout(()=>{
this.list=['快樂(lè)大本營(yíng)','腳踏實(shí)地','300033','天天向上','好好學(xué)習(xí)'],
console.log('created異步:',document.getElementsByTagName('li').length);
},1000)
},
mounted: function () {
console.log('mounted:',document.getElementsByTagName('li').length);
},
updated: function () {
console.log('updated:',document.getElementsByTagName('li').length)
},
結(jié)果為:

2.Vue.nextTick對(duì)異步函數(shù)的結(jié)果進(jìn)行操作
我們想要改變數(shù)據(jù)時(shí),各自觸發(fā)各自的方法
created:function(){
//異步獲取數(shù)據(jù)
// 因?yàn)槭钱惒?就和我們ajax獲取數(shù)據(jù)一樣
//為了在數(shù)據(jù)變化之后等待 Vue 完成更新 DOM ,可以在數(shù)據(jù)變化之后立即使用 Vue.nextTick(callback) 。這樣回調(diào)函數(shù)在 DOM 更新完成后就會(huì)調(diào)用。
setTimeout(()=>{
this.list=['111','222','333','444'],
console.log('created異步:',document.getElementsByTagName('li').length);
this.$nextTick(function(){
console.log("created$nextTick:",document.getElementsByTagName('li').length)
});
},0)
setTimeout(()=>{
this.list=['快樂(lè)大本營(yíng)','腳踏實(shí)地','300033','天天向上','好好學(xué)習(xí)'],
console.log('created異步:',document.getElementsByTagName('li').length);
this.$nextTick(function(){
console.log("created$nextTick:",document.getElementsByTagName('li').length)
});
},1000)
},
mounted: function () {
console.log('mounted:',document.getElementsByTagName('li').length);
},
updated: function () {
console.log('updated:',document.getElementsByTagName('li').length)
},
結(jié)果:
我們可以看到通過(guò)$nextTick我們可以對(duì)異步函數(shù)的結(jié)果進(jìn)行各自的操作
到此這篇關(guān)于對(duì)vue生命周期深入理解的文章就介紹到這了,更多相關(guān)vue生命周期的理解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue打包npm run build時(shí)候界面報(bào)錯(cuò)的解決
這篇文章主要介紹了vue打包npm run build時(shí)候界面報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
Vue使用echarts散點(diǎn)圖在區(qū)域內(nèi)標(biāo)點(diǎn)
這篇文章主要為大家詳細(xì)介紹了Vue使用echarts散點(diǎn)圖在區(qū)域內(nèi)標(biāo)點(diǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Vue?Router路由hash模式與history模式詳細(xì)介紹
Vue?Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,讓構(gòu)建單頁(yè)面應(yīng)用變得易如反掌。路由實(shí)際上就是可以理解為指向,就是我在頁(yè)面上點(diǎn)擊一個(gè)按鈕需要跳轉(zhuǎn)到對(duì)應(yīng)的頁(yè)面,這就是路由跳轉(zhuǎn)2022-08-08
Vue?router應(yīng)用問(wèn)題實(shí)戰(zhàn)記錄
vue-router是vue.js官方的路由插件,他和vue.js是深度集成的適合構(gòu)建單頁(yè)面應(yīng)用,下面這篇文章主要給大家介紹了關(guān)于Vue?router應(yīng)用問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04
Vue3+axios+Mock.js實(shí)現(xiàn)登錄功能的示例代碼
本文主要介紹了Vue3+axios+Mock.js實(shí)現(xiàn)登錄功能的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
vue實(shí)現(xiàn)垂直無(wú)限滑動(dòng)日歷組件
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)垂直無(wú)限滑動(dòng)日歷組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04

