- 什么是vue生命周期?
- Vue 實(shí)例從創(chuàng)建到銷毀的過程,就是生命周期。也就是從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載DOM-渲染、更新-渲染、卸載等一系列的過程,我們稱這是 Vue 的生命周期。
- vue生命周期的作用是什么
- Vue 所有的功能的實(shí)現(xiàn)都是圍繞其生命周期進(jìn)行的,在生命周期的不同階段調(diào)用對(duì)應(yīng)的鉤子函數(shù)可以實(shí)現(xiàn)組件數(shù)據(jù)管理和DOM渲染兩大重要功能。
- 生命周期中有多個(gè)事件鉤子,在控制整個(gè)vue實(shí)例的過程時(shí)更容易形成好的邏輯。
- 第一次頁面加載會(huì)觸發(fā)哪幾個(gè)鉤子?
- beforeCreate
實(shí)例剛在內(nèi)存中被創(chuàng)建出來---$el 和 data 都未初始化 - created
實(shí)例創(chuàng)建完成,模板尚未編譯---data 數(shù)據(jù)初始化完成, $el 未初始化 - beforeMount
模板編譯完成,但還沒掛載到頁面中---$el 和 data 初始化都完成了 - mounted
模板已編譯完成,并掛載到頁面指定的容器中---掛載完成 - beforeUpdate
狀態(tài)更新之前執(zhí)行此函數(shù), 此時(shí) data 中的狀態(tài)值是最新的,但是界面上顯示的 數(shù)據(jù)還是舊的,因?yàn)榇藭r(shí)還沒有開始重新渲染DOM節(jié)點(diǎn) - updated
實(shí)例更新完畢之后調(diào)用此函數(shù),此時(shí) data 中的狀態(tài)值 和 界面上顯示的數(shù)據(jù),都已經(jīng)完成了更新,界面已經(jīng)被重新渲染好了 - beforeDestroy
實(shí)例銷毀之前調(diào)用,在這一步,實(shí)例仍然完全可用 - destroyed
實(shí)例銷毀后調(diào)用,調(diào)用后,Vue 實(shí)例指示的所有東西都會(huì)解綁定,所有的事件監(jiān)聽器會(huì)被移除,所有的子實(shí)例也會(huì)被銷毀
- beforeCreate
總共分為8個(gè)階段:創(chuàng)建前/后,掛載前/后,更新前/后,銷毀前/后。
- 創(chuàng)建前/后: 在beforeCreated階段,vue實(shí)例的掛載元素$el和數(shù)據(jù)對(duì)象data都為undefined,還未初始化。在created階段,vue實(shí)例的數(shù)據(jù)對(duì)象data有了,$el還沒有。
- 掛載前/后:在beforeMount階段,vue實(shí)例的$el和data都初始化了,但還是掛載之前為虛擬的dom節(jié)點(diǎn),data.message還未替換。在mounted階段,vue實(shí)例掛載完成,data.message成功渲染。
- 更新前/后:當(dāng)data變化時(shí),會(huì)觸發(fā)beforeUpdate和updated方法。
- 銷毀前/后:在執(zhí)行destroy方法后,對(duì)data的改變不會(huì)再觸發(fā)周期函數(shù),說明此時(shí)vue實(shí)例已經(jīng)解除了事件監(jiān)聽以及和dom的綁定,但是dom結(jié)構(gòu)依然存在
<template>
<div id="app">
<div>{{msg}}</div>
<button @click="updateMsg">btn</button>
<button @click="destroyObj">destroy</button>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
msg: 'hello'
}
},
beforeCreate() {
console.log('------beforeCreate');
console.log(this.msg);
console.log(this.$el);
},
created() {
console.log('------created');
console.log(this.msg);
console.log(this.$el);
},
beforeMount() {
console.log('------beforeMount');
console.log(this.msg);
console.log(this.$el);
},
mounted() {
console.log('------mounted');
console.log(this.msg);
console.log(this.$el);
},
beforeUpdate() {
console.log('------beforeUpdate');
console.log(this.msg);
console.log(this.$el);
},
updated() {
console.log('------updated');
console.log(this.msg);
console.log(this.$el);
},
beforeDestroy() {
console.log('---beforeDestroy');
console.log(this.msg);
console.log(this.$el);
},
destroyed() {
console.log('---destroyed');
console.log(this.msg);
console.log(this.$el);
},
methods: {
updateMsg() {
this.msg = 'world'
},
destroyObj() {
this.$destroy()
}
}
}
</script>

image.png
-
簡述每個(gè)周期具體適合哪些場景?
image.png
- beforeCreate:創(chuàng)建前,此階段為實(shí)例初始化之后,this指向創(chuàng)建的實(shí)例,此時(shí)的數(shù)據(jù)觀察事件機(jī)制都未形成,不能獲得DOM節(jié)點(diǎn)。
- data,computed,watch,methods 上的方法和數(shù)據(jù)均不能訪問。
- 可以在這加個(gè)loading事件。
- created:創(chuàng)建后,此階段為實(shí)例已經(jīng)創(chuàng)建,完成數(shù)據(jù)(data、props、computed)的初始化導(dǎo)入依賴項(xiàng)。
- 可訪問 data computed watch methods 上的方法和數(shù)據(jù)。
- 初始化完成時(shí)的事件寫在這里,異步請(qǐng)求也適宜在這里調(diào)用(請(qǐng)求不宜過多,避免白屏?xí)r間太長)。
- 可以在這里結(jié)束loading事件,還做一些初始化,實(shí)現(xiàn)函數(shù)自執(zhí)行。
- 未掛載DOM,若在此階段進(jìn)行DOM操作一定要放在Vue.nextTick()的回調(diào)函數(shù)中。
- beforeMount:掛載前,雖然得不到具體的DOM元素,但vue掛載的根節(jié)點(diǎn)已經(jīng)創(chuàng)建,下面vue對(duì)DOM的操作將圍繞這個(gè)根元素繼續(xù)進(jìn)行。
- beforeMount這個(gè)階段是過渡性的,一般一個(gè)項(xiàng)目只能用到一兩次。
- mounted:掛載,完成創(chuàng)建vm.$el,和雙向綁定
- 完成掛載DOM和渲染,可在mounted鉤子函數(shù)中對(duì)掛載的DOM進(jìn)行操作。
- 可在這發(fā)起后端請(qǐng)求,拿回?cái)?shù)據(jù),配合路由鉤子做一些事情。
- beforeUpdate:數(shù)據(jù)更新前,數(shù)據(jù)驅(qū)動(dòng)DOM。
- 在數(shù)據(jù)更新后雖然沒有立即更新數(shù)據(jù),但是DOM中的數(shù)據(jù)會(huì)改變,這是vue雙向數(shù)據(jù)綁定的作用。
- 可在更新前訪問現(xiàn)有的DOM,如手動(dòng)移出添加的事件監(jiān)聽器。
- updated:數(shù)據(jù)更新后,完成虛擬DOM的重新渲染和打補(bǔ)丁。
- 組件DOM已完成更新,可執(zhí)行依賴的DOM操作。
- 注意:不要在此函數(shù)中操作數(shù)據(jù)(修改屬性),會(huì)陷入死循環(huán)。
- activated:在使用vue-router時(shí)有時(shí)需要使用<keep-alive></keep-alive>來緩存組件狀態(tài),這個(gè)時(shí)候created鉤子就不會(huì)被重復(fù)調(diào)用了。
- 如果我們的子組件需要在每次加載的時(shí)候進(jìn)行某些操作,可以使用activated鉤子觸發(fā)。
- deactivated:<keep-alive></keep-alive>組件被移除時(shí)使用。
- beforeDestroy:銷毀前,
- 可做一些刪除提示,如:您確定刪除xx嗎?
- destroyed:銷毀后,當(dāng)前組件已被刪除,銷毀監(jiān)聽事件,組件、事件、子實(shí)例也被銷毀。
- 這時(shí)組件已經(jīng)沒有了,無法操作里面的任何東西了。
- 父子組件的生命周期
執(zhí)行順序:
- 父組件開始執(zhí)行到beforeMount 然后開始子組件執(zhí)行,最后是父組件mounted
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted- 如果有兄弟組件,父組件開始執(zhí)行到beforeMount,然后兄弟組件依次執(zhí)行到beforeMount,然后按照順序執(zhí)行mounted,最后執(zhí)行父組件的mounted。
- 當(dāng)子組件掛載完成后,父組件才會(huì)掛載。
- 當(dāng)子組件完成掛載后,父組件會(huì)主動(dòng)執(zhí)行一次beforeUpdated/updated鉤子函數(shù)(僅首次)
- 父子組件在data變化中是分別監(jiān)控的,但是更新props中的數(shù)據(jù)是關(guān)聯(lián)的
父beforeUpdate->子beforeUpdate->子updated->父updated- 銷毀父組件時(shí),先將子組件銷毀后才會(huì)銷毀父組件
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed- 兄弟組件的初始化(mounted之前)是分開進(jìn)行,掛載是從上到下依次進(jìn)行
- 當(dāng)沒有數(shù)據(jù)關(guān)聯(lián)時(shí),兄弟組件之間的更新和銷毀是互不關(guān)聯(lián)的
