Vue.js學習(四):父子組件中的生命週期與鉤子函數的調用順序

借用下面這張圖先簡單瞭解Vue的整個生命週期


<div id="app">
    <child></child>
    <button @click="msg++">increase</button>
    <h2>{{msg}}</h2>
    <button @click="destroy">destroy</button>
</div>


一、創建與掛載(created  and mounted)

當一個父組件中加載一個子組件,且父組件和子組件中同時調用mixin函數時,整個生命週期的順序爲:

1、創建父組件

beforeCreate:父組件中的mixins--父組件--子組件中的mixins--子組件

created:父組件中的mixins--父組件

2、掛載父組件之前

beforeMount:父組件中的mixins--父組件

1) 創建子組件

beforeCreate:子組件中的mixins--子組件

created:子組件中的mixins--子組件

2) 掛載子組件之前

beforeMount:子組件中的mixins--子組件

3、掛載子組件

mounted:子組件中的mixins--子組件

4、掛載父組件

mounted:父組件中的mixins--父組件


總的來說,從創建到掛載,是從外到內,再從內到外,且mixins的鉤子函數總是在當前組件之前執行

let mixin={
    beforeCreate(){
        console.log('mixins beforeCreate')
    },
    created(){
        console.log('mixins created')
    },
    beforeMount(){
        console.log('mixins beforeMount')
    },
    mounted(){
        console.log('mixins mounted')
    },
    beforeUpdate: function(){
        console.log('mixins beforeUpdate')
    },
    updated: function(){
        console.log('mixins updated')
    },
    beforeDestroy: function(){
        console.log('mixins beforeDestroy')
    },
    destroyed: function(){
        console.log('mixins destroyed')
    },
    data(){
        return{
            msg:1
        }
    },
    methods:{
        foo(){
            console.log('mixin foo()'+this.msg++)
        }
    }
}


var child=Vue.component('child',{
    template:`<h1 @click="foo">child component+"--"+{{msg}}</h1>`,
    mixins:[mixin],
    beforeCreate(){
        console.log('child beforeCreate')
    },
    created(){
        console.log('child created')
    },
    beforeMount(){
        console.log('child beforeMount')
    },
    mounted(){
        console.log('child mounted')
    },
    beforeUpdate: function(){
        console.log('child beforeUpdate')
    },
    updated: function(){
        console.log('child updated')
    },
    beforeDestroy: function(){
        console.log('child beforeDestroy')
    },
    destroyed: function(){
        console.log('child destroyed')
    },
    data(){
        return{
            msg: 2
        }
    },
    methods:{
        foo(){
            console.log('Child foo()'+this.msg++)
        }
    }
})




let vm=new Vue({
    el:"#app",
    data:{
        msg: 3
    },
    mixins:[mixin],
    methods:{
        foo(){
            console.log('Parent foo()'+this.msg++)
        },
        destroy(){
            vm.$destroy();
        }
    },
    beforeCreate: function(){
        console.log('app beforeCreate')
    },
    created: function(){
        console.log('app created')
    },
    beforeMount: function(){
        console.log('app beforeMount')
    },
    mounted: function(){
        console.log('app mounted')
        console.log('app say hi')
    },
    beforeUpdate: function(){
        console.log('app beforeUpdate')
    },
    updated: function(){
        console.log('app updated')
    },
    beforeDestroy: function(){
        console.log('app beforeDestroy')
    },
    destroyed: function(){
        console.log('app destroyed')
    }
})


如果引入自定義指令:

Vue.directive('init',{
    bind:function(el){
        console.log('directive init created')
    }
})

<child v-init></child>
則自定義指定的鉤子函數,相當於組件的created+mounted,且在子組件掛載之後觸發。



二、數據更新(updated)

只有在標籤上綁定了data時,data發生改變,纔會觸發updated鉤子函數。如果只是在控制檯改變data,而沒有反饋到視圖上,則無法觸發。

當data中的數據改變時,不會觸發子組件中的updated函數。觸發的順序仍然是mixins先於組件

單擊increase按鈕,控制檯的數據顯示如下



三、組件銷燬(destroy)

組件銷燬的順序跟創建的順序類似,還是尊重“從外到內,再從內到外,mixins先於組件”這樣的原則。但是,小編嘗試過,綁定在子組件中的事件仍然可以調用(這點我也很奇怪)。



總結:生命週期遵從“從外到內,再從內到外,mixins先於組件”的原則。

如有缺漏,請指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章