詳解vue生命周期
為什么要理解生命周期
用Vue框架,熟悉它的生命周期可以讓開發(fā)更好的進行。
如果只是單純地知道vue里面的簡單語法,你是可以實現(xiàn)對應(yīng)的一些項目和對應(yīng)的想法,但是如果一旦發(fā)生問題,我們就需要借助生命周期去尋找問題,甚至說有一些需求的話,你也通過生命周期的情況來定我們該把這個東西寫在哪里。所以理解vue的生命周期還是很有必要的
什么是生命周期
Vue實例從創(chuàng)建到銷毀的過程,就是生命周期。詳細(xì)來說也就是從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom、渲染→更新→渲染、卸載等一系列過程。
另外補充一點,Vue的實例,它是Vue框架的入口,可以理解為前端的ViewModel,它包含了頁面中的業(yè)務(wù)邏輯處理、數(shù)據(jù)模型等,它也有自己的一系列的生命周期的函數(shù)鉤子,輔助我們進行對整個Vue實例生成、編譯、掛著、銷毀等過程進行js控制。
官網(wǎng)給出的生命周期圖(翻譯成中文)如下:
生命周期鉤子函數(shù)
生命周期鉤子,就是生命周期事件的別名而已,生命周期鉤子 = 生命周期函數(shù) = 生命周期事件
主要的生命周期函數(shù)分類:
創(chuàng)建期間的生命周期函數(shù):
beforeCreate:實例剛在內(nèi)存中被創(chuàng)建出來,此時,還沒有初始化好 data 和 methods 屬性
created:實例已經(jīng)在內(nèi)存中創(chuàng)建OK,此時 data 和 methods 已經(jīng)創(chuàng)建OK,此時還沒有開始 編譯模板
beforeMount:此時已經(jīng)完成了模板的編譯,但是還沒有掛載到頁面中
mounted:此時,已經(jīng)將編譯好的模板,掛載到了頁面指定的容器中顯示
運行期間的生命周期函數(shù):
beforeUpdate:狀態(tài)更新之前執(zhí)行此函數(shù), 此時 data 中的狀態(tài)值是最新的,但是界面上顯示的 數(shù)據(jù)還是舊的,因為此時還沒有開始重新渲染DOM節(jié)點
updated:實例更新完畢之后調(diào)用此函數(shù),此時 data 中的狀態(tài)值 和 界面上顯示的數(shù)據(jù),都已經(jīng)完成了更新,界面已經(jīng)被重新渲染好了!
銷毀期間的生命周期函數(shù):
beforeDestroy:實例銷毀之前調(diào)用。在這一步,實例仍然完全可用。
destroyed:Vue 實例銷毀后調(diào)用。調(diào)用后,Vue 實例指示的所有東西都會解除綁定,所有的事件監(jiān)聽器會被移除,所有的子實例也會被銷毀。
created和mounted
在生命周期鉤子函數(shù)中,最常用的應(yīng)該就是created和mounted了。
created:在模板渲染成html前調(diào)用,即通常初始化某些屬性值,然后再渲染成視圖。主要應(yīng)用:調(diào)用數(shù)據(jù),調(diào)用方法,調(diào)用異步函數(shù)
mounted:在模板渲染成html后調(diào)用,通常是初始化頁面完成后,再對html的dom節(jié)點進行一些需要的操作。
在created的時候,視圖中的html并沒有渲染出來,所以此時如果直接去操作html的dom節(jié)點,一定找不到相關(guān)的元素
而在mounted中,由于此時html已經(jīng)渲染出來了,所以可以直接操作dom節(jié)點,
其實兩者比較好理解,通常created使用的次數(shù)多,而mounted通常是在一些插件的使用或者組件的使用中進行操作,比如插件chart.js的使用: var ctx = document.getElementById(ID); 通常會有這一步,而如果你寫入組件中,你會發(fā)現(xiàn)在created中無法對chart進行一些初始化配置,一定要等這個html渲染完后才可以進行,那么mounted就是不二之選。
鉤子的一些實戰(zhàn)用法
1.異步函數(shù)
這里我們用定時器來做異步函數(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ù) // 因為是異步,就和我們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
解釋:
可以看到因為是在created的鉤子中加入異步函數(shù),所以函數(shù)的執(zhí)行順序為:
ceated鉤子,mounted鉤子,異步函數(shù),updated鉤子(根據(jù)事件隊列原理,只有在updated后,li才是真的DOM渲染為4個,所以異步函數(shù)中獲取的li的個數(shù)時是沒有變化的li的個數(shù))。
因為mounted獲取到的是我們在Vue的data中設(shè)置初始值渲染的DOM,而我們是在異步函數(shù)中變化的list數(shù)據(jù),所以mounted獲取的li的個數(shù)為3。
update函數(shù)是只要數(shù)據(jù)vue綁定的數(shù)據(jù)變化就會觸發(fā),所以最后執(zhí)行,為4
這是不是意味著可以直接在update函數(shù)中操作呢,其實不是,因為update函數(shù)是針對vue的所有數(shù)據(jù)的變化,而我們也有可能會有其他數(shù)據(jù)的變化。
例如下面的例子:
//我們利用異步函數(shù)改變了兩次list,會發(fā)現(xiàn)update被觸發(fā)了2次 created:function(){ //異步獲取數(shù)據(jù) // 因為是異步,就和我們ajax獲取數(shù)據(jù)一樣 setTimeout(()=>{ this.list=['111','222','333','444'], console.log('created異步:',document.getElementsByTagName('li').length); },0) setTimeout(()=>{ this.list=['快樂大本營','腳踏實地','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對異步函數(shù)的結(jié)果進行操作
我們想要改變數(shù)據(jù)時,各自觸發(fā)各自的方法
created:function(){ //異步獲取數(shù)據(jù) // 因為是異步,就和我們ajax獲取數(shù)據(jù)一樣 //為了在數(shù)據(jù)變化之后等待 Vue 完成更新 DOM ,可以在數(shù)據(jù)變化之后立即使用 Vue.nextTick(callback) 。這樣回調(diào)函數(shù)在 DOM 更新完成后就會調(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=['快樂大本營','腳踏實地','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é)果為:
我們可以看到通過$nextTick我們可以對異步函數(shù)的結(jié)果進行各自的操作
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
詳解關(guān)于vue2.0工程發(fā)布上線操作步驟
這篇文章主要介紹了詳解關(guān)于vue2.0工程發(fā)布上線操作步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09Vue-router 類似Vuex實現(xiàn)組件化開發(fā)的示例
本篇文章主要介紹了Vue-router 類似Vuex實現(xiàn)組件化開發(fā)的示例,具有一定的參考價值,有興趣的可以了解一下2017-09-09vuex?mutations的兩種調(diào)用方法小結(jié)
這篇文章主要介紹了vuex?mutations的兩種調(diào)用方法小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03