vue 生命周期中的鉤子函數(shù)及父子組件的執(zhí)行順序

先附一張官網(wǎng)上的vue實例的生命周期圖昨悼,每個Vue實例在被創(chuàng)建的時候都需要經(jīng)過一系列的初始化過程,例如需要設置數(shù)據(jù)監(jiān)聽跃洛,編譯模板率触,將實例掛載到DOM并在數(shù)據(jù)變化時更新DOM等。同時在這個過程中也會運行一些叫做生命周期鉤子的函數(shù)(回調(diào)函數(shù))汇竭,這給了用戶在不同階段添加自己代碼的機會葱蝗。

1.VUE的生命周期圖

vue的生命周期圖

在vue實例的整個生命周期的各個階段,會提供不同的鉤子函數(shù)以供我們進行不同的操作细燎。先列出vue官網(wǎng)上對各個鉤子函數(shù)的詳細解析两曼。

生命周期

2、實際操作

下面我們在實際的代碼執(zhí)行過程中理解父子組件生命周期創(chuàng)建過程以及鉤子函數(shù)執(zhí)行的實時狀態(tài)變化玻驻。

測試基于下面的代碼悼凑,引入vue.js文件后即可執(zhí)行。(打開頁面后击狮,再按一次刷新會自動進入debugger狀態(tài))

<!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>Document</title>
    <style>
        
    </style>
</head>   
<body>
<div id="app">
    <p>{{message}}</p>
    <keep-alive>
        <my-components :msg="msg1" v-if="show"></my-components>
    </keep-alive>
</div>
</body>
<script src="../../node_modules/vue/dist/vue.js"></script>
<script>
    var child = {
        template: '<div>from child: {{childMsg}}</div>',
        props: ['msg'],
        data: function() {
            return {
                childMsg: 'child'
            }   
        },
        beforeCreate: function () {
            debugger;
        },
        created: function () {
            debugger;
        },
        beforeMount: function () {
            debugger;
        },
        mounted: function () {
            debugger;
        },
        deactivated: function(){
            alert("keepAlive停用");
        },
        activated: function () {
            console.log('component activated');
        },
        beforeDestroy: function () {
            console.group('beforeDestroy 銷毀前狀態(tài)===============》');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        destroyed: function () {
            console.group('destroyed 銷毀完成狀態(tài)===============》');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
    };
    var vm = new Vue({
        el: '#app',
        data: {
                message: 'father',
                msg1: "hello",
                show: true
            },
        beforeCreate: function () {
            debugger;
        },
        created: function () {
            debugger;
        },
        beforeMount: function () {
            debugger;
        },
        mounted: function () {
            debugger;    
        },
        beforeUpdate: function () {
            alert("頁面視圖更新前");
            
        },
        updated: function () {
            alert("頁面視圖更新后");
        },
        beforeDestroy: function () {
            console.group('beforeDestroy 銷毀前狀態(tài)===============》');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        destroyed: function () {
            console.group('destroyed 銷毀完成狀態(tài)===============》');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        components: {
            'my-components': child
        }
    });
</script>
</html>

3.1佛析、生命周期調(diào)試

首先我們創(chuàng)建了一個Vue實例vm,將其掛載到頁面中id為“app”的元素上彪蓬。

3.1.1寸莫、根組件的beforeCreate階段

根組件的beforeCreate階段

可以看出,在調(diào)用beforeCreate()函數(shù)時档冬,只進行了一些必要的初始化操作(例如一些全局的配置和根實例的一些屬性初始化)膘茎,此時data屬性為undefined,沒有可供操作的數(shù)據(jù)酷誓。

3.1.2披坏、根組件的created階段

根組件的created階段

調(diào)用Created()函數(shù),在這一步盐数,實例已完成以下的配置:數(shù)據(jù)代理和動態(tài)數(shù)據(jù)綁定(data observer)棒拂,屬性和方法的運算, watch/event 事件回調(diào)。然而帚屉,掛載階段還沒開始谜诫,$el 屬性目前不可見。

3.1.3攻旦、根組件的beforeMount階段

根組件的beforeMount階段

在調(diào)用boforeMount()函數(shù)前首先會判斷對象是否有el選項喻旷。如果有的話就繼續(xù)向下編譯,如果沒有el選項牢屋,則停止編譯且预,也就意味著停止了生命周期,直到在該vue實例上調(diào)用vm.$mount(el)

在這個例子中烙无,我們有el元素锋谐,因此會調(diào)用boforeMount()函數(shù),此時已經(jīng)開始執(zhí)行模板解析函數(shù),但還沒有將$el元素掛載頁面皱炉,頁面視圖因此也未更新怀估。在標紅處,還是 {{message}},這里就是應用的 Virtual DOM(虛擬Dom)技術免钻,先把坑占住了庸追。到后面mounted掛載的時候再把值渲染進去

3.1.4、子組件的beforeCreate际乘、created、beforeMount、mounted階段

子組件的beforeCreate赌髓、created、beforeMount催跪、mounted階段

在父組件執(zhí)行beforeMount階段后锁蠕,進入子組件的beforeCreate、created懊蒸、beforeMount階段荣倾,這些階段和父組件類似,按下不表骑丸。beforeMount階段后舌仍,執(zhí)行的是mounted階段,該階段時子組件已經(jīng)掛載到父組件上通危,并且父組件隨之掛載到頁面中铸豁。

在beforeMount階段之后、Mounted階段之前菊碟,數(shù)據(jù)已經(jīng)被加載到視圖上了节芥,即$el元素被掛載到頁面時觸發(fā)了視圖的更新。

3.1.5逆害、子組件的activated階段

子組件的activated階段

我們發(fā)現(xiàn)在子父組件全部掛載到頁面之后被觸發(fā)头镊。這是因為子組件my-components被<keep-alive> 包裹增炭,隨$el的掛載被觸發(fā)。如果子組件沒有被<keep-alive>包裹拧晕,那么該階段將不會被觸發(fā)隙姿。

3.1.6、父組件的mounted階段

mounted執(zhí)行時:此時el已經(jīng)渲染完成并掛載到實例上厂捞。

至此输玷,從Vue實例的初始化到將新的模板掛載到頁面上的階段已經(jīng)完成,退出debugger靡馁。
下面我們來看一下deactivated欲鹏、beforeUpdate、updated臭墨、beforeDestroy赔嚎、destroyed鉤子函數(shù)。

3.2胧弛、deactivated尤误、beforeUpdate、updated階段

由生命周期函數(shù)可知:當數(shù)據(jù)變化后结缚、虛擬DOM渲染重新渲染頁面前會觸發(fā)beforeUpdate()函數(shù)损晤,此時視圖還未改變。當虛擬DOM渲染頁面視圖更新后會觸發(fā)updated()函數(shù)红竭。

deactivated尤勋、beforeUpdate、updated

我們不妨改變vm.show = false茵宪,當修改這個屬性時最冰,不僅會觸發(fā)beforeUpdate、updated函數(shù)稀火,還會觸發(fā)deactivated函數(shù)(因為keep-alive 組件停用時調(diào)用)暖哨。我們不妨想一下deactivated函數(shù)會在beforeUpdate后還是updated后調(diào)用。

我們在控制臺輸入vm.show = false憾股。得到三者的調(diào)用順序分別為beforeUpdate鹿蜀、deactivated、updated服球。我們可以知道的是deactivated函數(shù)的觸發(fā)時間是在視圖更新時觸發(fā)茴恰。因為當視圖更新時才能知道keep-alive組件被停用了。

deactivated

3.3斩熊、beforeDestroy和destroyed鉤子函數(shù)間的生命周期

現(xiàn)在我們對Vue實例進行銷毀往枣,調(diào)用app.$destroy()方法即可將其銷毀,控制臺測試如下:

image.png

我們發(fā)現(xiàn)實例依然存在,但是此時變化已經(jīng)發(fā)生在了其他地方分冈。

beforeDestroy鉤子函數(shù)在實例銷毀之前調(diào)用圾另。在這一步,實例仍然完全可用雕沉。

destroyed鉤子函數(shù)在Vue 實例銷毀后調(diào)用集乔。調(diào)用后,Vue 實例指示的所有東西都會解綁定坡椒,所有的事件監(jiān)聽器會被移除扰路,所有的子實例也會被銷毀(也就是說子組件也會觸發(fā)相應的函數(shù))。這里的銷毀并不指代'抹去'倔叼,而是表示'解綁'汗唱。

銷毀時beforeDestory函數(shù)的傳遞順序為由父到子,destory的傳遞順序為由子到父丈攒。

4哩罪、一些應用鉤子函數(shù)的想法

  • 在created鉤子中可以對data數(shù)據(jù)進行操作,這個時候可以進行ajax請求將返回的數(shù)據(jù)賦給data巡验。
  • 雖然updated函數(shù)會在數(shù)據(jù)變化時被觸發(fā)际插,但卻不能準確的判斷是那個屬性值被改變,所以在實際情況中用computed或match函數(shù)來監(jiān)聽屬性的變化深碱,并做一些其他的操作腹鹉。
  • 在mounted鉤子對掛載的dom進行操作,此時敷硅,DOM已經(jīng)被渲染到頁面上。
  • 在使用vue-router時有時需要使用<keep-alive></keep-alive>來緩存組件狀態(tài)愉阎,這個時候created鉤子就不會被重復調(diào)用了绞蹦,如果我們的子組件需要在每次加載或切換狀態(tài)的時候進行某些操作,可以使用activated鉤子觸發(fā)榜旦。
  • 所有的生命周期鉤子自動綁定 this 上下文到實例中幽七,所以不能使用箭頭函數(shù)來定義一個生命周期方法 (例如 created: () => this.fetchTodos())。這是導致this指向父級溅呢。

5澡屡、 小結

  • 加載渲染過程

父 beforeCreate => 父 created => 父 beforeMount => 子 beforeCreate => 子 created => 子 beforeMount => 子 mounted => 父 mounted

  • 子組件更新過程

父 beforeUpdate => 子 beforeUpdate => 子 updated => 父 updated

  • 父組件更新過程

父 beforeUpdate => 父 updated

  • 銷毀過程

父 beforeDestroy => 子 beforeDestroy => 子 destroyed => 父 destroyed

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市咐旧,隨后出現(xiàn)的幾起案子驶鹉,更是在濱河造成了極大的恐慌,老刑警劉巖铣墨,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件室埋,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機姚淆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門孕蝉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腌逢,你說我怎么就攤上這事降淮。” “怎么了搏讶?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵佳鳖,是天一觀的道長。 經(jīng)常有香客問我窍蓝,道長腋颠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任吓笙,我火速辦了婚禮淑玫,結果婚禮上,老公的妹妹穿的比我還像新娘面睛。我一直安慰自己絮蒿,他們只是感情好,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布叁鉴。 她就那樣靜靜地躺著土涝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪幌墓。 梳的紋絲不亂的頭發(fā)上但壮,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機與錄音常侣,去河邊找鬼蜡饵。 笑死,一個胖子當著我的面吹牛胳施,可吹牛的內(nèi)容都是我干的溯祸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼舞肆,長吁一口氣:“原來是場噩夢啊……” “哼焦辅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起椿胯,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤筷登,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后压状,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仆抵,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡跟继,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了镣丑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舔糖。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖莺匠,靈堂內(nèi)的尸體忽然破棺而出金吗,到底是詐尸還是另有隱情,我是刑警寧澤趣竣,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布摇庙,位于F島的核電站,受9級特大地震影響遥缕,放射性物質(zhì)發(fā)生泄漏卫袒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一单匣、第九天 我趴在偏房一處隱蔽的房頂上張望夕凝。 院中可真熱鬧,春花似錦户秤、人聲如沸码秉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽转砖。三九已至,卻和暖如春鲸伴,著一層夾襖步出監(jiān)牢的瞬間府蔗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工汞窗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留礁竞,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓杉辙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捶朵。 傳聞我的和親對象是個殘疾皇子蜘矢,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容