Vue生命周期詳解
這篇博客將會從下面四個常見的應(yīng)用詮釋組件的生命周期,以及各個生命周期應(yīng)該干什么事
- 單組件的生命周期
- 父子組件的生命周期
- 兄弟組件的生命周期
- 宏mixin的生命周期
生命周期:Vue 實例從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是 Vue 的生命周期,各個階段有相對應(yīng)的事件鉤子
1. 生命周期鉤子函數(shù)
下面這張圖是vue生命周期各個階段的執(zhí)行情況:
注意:
created階段的ajax請求與mounted請求的區(qū)別:前者頁面視圖未出現(xiàn),如果請求信息過多,頁面會長時間處于白屏狀態(tài)
mounted 不會承諾所有的子組件也都一起被掛載。如果你希望等到整個視圖都渲染
完畢,可以用 vm.$nextTick
vue2.0之后主動調(diào)用$destroy()不會移除dom節(jié)點,作者不推薦直接destroy這種做法,如果實在需要這樣用可以在這個生命周期鉤子中手動移除dom節(jié)點
2. 單個組件的生命周期
現(xiàn)根據(jù)實際代碼執(zhí)行情況分析:
<template> <div> <h3>單組件</h3> <el-button @click="dataVar += 1">更新 {{dataVar}}</el-button> <el-button @click="handleDestroy">銷毀</el-button> </div> </template> export default { data() { return { dataVar: 1 } }, beforeCreate() { this.compName = 'single' console.log(`--${this.compName}--beforeCreate`) }, created() { console.log(`--${this.compName}--created`) }, beforeMount() { console.log(`--${this.compName}--beforeMount`) }, mounted() { console.log(`--${this.compName}--mounted`) }, beforeUpdate() { console.log(`--${this.compName}--beforeUpdate`) }, updated() { console.log(`--${this.compName}--updated`) }, beforeDestroy() { console.log(`--${this.compName}--beforeDestroy`) }, destroyed() { console.log(`--${this.compName}--destroyed`) }, methods: { handleDestroy() { this.$destroy() } } }
初始化組件時,打印:
當(dāng)data中的值變化時,打?。?/p>
當(dāng)組件銷毀時,打?。?/p>
從打印結(jié)果可以看出:
初始化組件時,僅執(zhí)行了beforeCreate/Created/beforeMount/mounted四個鉤子函數(shù)
當(dāng)改變data中定義的變量(響應(yīng)式變量)時,會執(zhí)行beforeUpdate/updated鉤子函數(shù)
當(dāng)切換組件(當(dāng)前組件未緩存)時,會執(zhí)行beforeDestory/destroyed鉤子函數(shù)
初始化和銷毀時的生命鉤子函數(shù)均只會執(zhí)行一次,beforeUpdate/updated可多次執(zhí)行
3. 父子組件的生命周期
將單組件作為基礎(chǔ)組件(由于props在beforeCreate()中未初始化),需要做如下更改:
props: { compName: { type: String, default: 'single' } }, beforeCreate() { // this.compName = 'single' // console.log(`--${this.compName}--beforeCreate`) console.log(` --data未初始化--beforeCreate`) },
父組件代碼如下:
<template> <div class="complex"> <h3>復(fù)雜組件</h3> <lifecycle-single compName="child"></lifecycle-single> </div> </template> const COMPONENT_NAME = 'complex' import LifecycleSingle from './LifeCycleSingle' export default { beforeCreate() { console.log(`--${COMPONENT_NAME}--beforeCreate`) }, created() { console.log(`--${COMPONENT_NAME}--created`) }, beforeMount() { console.log(`--${COMPONENT_NAME}--beforeMount`) }, mounted() { console.log(`--${COMPONENT_NAME}--mounted`) }, beforeUpdate() { console.log(`--${COMPONENT_NAME}--beforeUpdate`) }, updated() { console.log(`--${COMPONENT_NAME}--updated`) }, beforeDestroy() { console.log(`--${COMPONENT_NAME}--beforeDestroy`) }, destroyed() { console.log(`--${COMPONENT_NAME}--destroyed`) }, components: { LifecycleSingle } }
初始化組件時,打印:
當(dāng)子組件data中的值變化時,打?。?/p>
當(dāng)父組件data中的值變化時,打印:
當(dāng)props改變時,打印:
當(dāng)子組件銷毀時,打印:
當(dāng)父組件銷毀時,打?。?/p>
從打印結(jié)果可以看出:
僅當(dāng)子組件完成掛載后,父組件才會掛載
當(dāng)子組件完成掛載后,父組件會主動執(zhí)行一次beforeUpdate/updated鉤子函數(shù)(僅首次)
父子組件在data變化中是分別監(jiān)控的,但是在更新props中的數(shù)據(jù)是關(guān)聯(lián)的(可實踐)
銷毀父組件時,先將子組件銷毀后才會銷毀父組件
4. 兄弟組件的生命周期
在上面的基礎(chǔ)上,復(fù)雜組件做如下更改
<template> <div class="complex"> <h3>復(fù)雜組件</h3> <lifecycle-single compName="cihld1"></lifecycle-single> <lifecycle-single compName="child2"></lifecycle-single> <el-button @click="dataVar += 1">complex更新 {{dataVar}}</el-button> <el-button @click="handleDestroy">complex銷毀</el-button> </div> </template>
初始化組件時,打?。?/p>
當(dāng)child1更新和銷毀時,打印:
當(dāng)child2更新和銷毀時,打?。?/p>
當(dāng)父組件銷毀時,打印
從打印結(jié)果可以看出:
組件的初始化(mounted之前)分開進(jìn)行,掛載是從上到下依次進(jìn)行
當(dāng)沒有數(shù)據(jù)關(guān)聯(lián)時,兄弟組件之間的更新和銷毀是互不關(guān)聯(lián)的
5. 宏mixin的生命周期
在上面的基礎(chǔ)上,添加一個mixin.js文件,內(nèi)容如下:
const COMPONENT_NAME = 'lifecycleMixin' export default { name: COMPONENT_NAME, beforeCreate() { console.log(`--${COMPONENT_NAME}--beforeCreate`) }, created() { console.log(`--${COMPONENT_NAME}--created`) }, beforeMount() { console.log(`--${COMPONENT_NAME}--beforeMount`) }, mounted() { console.log(`--${COMPONENT_NAME}--mounted`) }, beforeUpdate() { console.log(`--${COMPONENT_NAME}--beforeUpdate`) }, updated() { console.log(`--${COMPONENT_NAME}--updated`) }, beforeDestroy() { console.log(`--${COMPONENT_NAME}--beforeDestroy`) }, destroyed() { console.log(`--${COMPONENT_NAME}--destroyed`) } }
同樣的,復(fù)雜組件做如下更改:
import lifecycleMixin from './mixin' export default { mixins: [lifecycleMixin], // ... }
組件初始化時,打?。?/p>
組件銷毀時,打?。?/p>
從打印結(jié)果可以看出:
- mixin中的生命周期與引入該組件的生命周期是僅僅關(guān)聯(lián)的,且mixin的生命周期優(yōu)先執(zhí)行
到此這篇關(guān)于Vue生命周期的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue3中watch監(jiān)聽對象的屬性值(監(jiān)聽源必須是一個getter函數(shù))
這篇文章主要介紹了Vue3中watch監(jiān)聽對象的屬性值,監(jiān)聽源必須是一個getter函數(shù),本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12vue3中使用@vueuse/core中的圖片懶加載案例詳解
這篇文章主要介紹了vue3中使用@vueuse/core中的圖片懶加載案例,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03Vue.js第二天學(xué)習(xí)筆記(vue-router)
這篇文章主要為大家詳細(xì)介紹了Vue.js第二天的學(xué)習(xí)筆記,關(guān)于vue-router的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12