實(shí)例生命周期

什么是生命周期

從Vue實(shí)例創(chuàng)建、運(yùn)行到銷毀期間,總是伴隨著各種各樣的事件,而Vue實(shí)例從創(chuàng)建到銷毀完畢的過(guò)程,便稱為Vue實(shí)例的生命周期。

生命周期圖示

lifecycle.png

配合代碼以更清晰的理解幾個(gè)鉤子的調(diào)用時(shí)機(jī)及用法:

<!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>Vue的生命周期</title>
</head>
<body>
    <div id="app">
        <h3 id="h3">{{ msg }}</h3>
        <input type="button" value="修改msg" @click="msg='no'">
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            msg: 'ok'
        },
        methods: {
            show: function(){
                console.log('執(zhí)行了show方法');
            }
        },
        // 首先是實(shí)例初始化(即實(shí)例創(chuàng)建)階段的4個(gè)鉤子
        beforeCreate() { // 第一個(gè)生命周期函數(shù),表示實(shí)例被完全創(chuàng)建出來(lái)前,會(huì)執(zhí)行它
            console.log(this.msg); // undefined
            this.show(); // TypeError: this.show is not a function
            // 由上可知,在beforeCreate鉤子執(zhí)行的時(shí)候,data和methods中的函數(shù)都還沒(méi)有被初始化。
        },
        created() { // 這是遇到的第二個(gè)生命周期函數(shù)
            console.log(this.msg); // ok
            this.show(); // 執(zhí)行了show方法
            // 可見(jiàn),在created中,data和methods都已經(jīng)被初始化好了。如果要調(diào)用methods中的方法,或者要調(diào)用data中的數(shù)據(jù),最早也要在created進(jìn)行操作。
            
        },
        beforeMount(){ /* 這是遇到的第三個(gè)生命周期函數(shù),表示模板已經(jīng)在內(nèi)存中編譯完成了,但是尚未把模板
                        渲染到頁(yè)面中去 */
            console.log(document.getElementById('h3').innerText); // {{ msg }}
            // 由上可見(jiàn),在beforeMount執(zhí)行的時(shí)候,頁(yè)面中的元素還沒(méi)有被真正替換過(guò)來(lái),只會(huì)輸出提前寫(xiě)好的模板字符串
        },
        mounted(){ /* 這是遇到的第四個(gè)生命周期函數(shù),此時(shí)內(nèi)存中編譯好的模板已經(jīng)被掛載到瀏覽器頁(yè)面中,
                    所以可以正確取出渲染后的內(nèi)容 */
            console.log(document.getElementById('h3').innerText); // ok
            /* mounted時(shí)創(chuàng)建實(shí)例時(shí)期的最后一個(gè)鉤子,執(zhí)行完mounted就表示實(shí)例已經(jīng)創(chuàng)建完畢,此時(shí)若沒(méi)有其他對(duì)實(shí)例進(jìn)行的操作,
                則實(shí)例不會(huì)有所更改 */
        },

        // 接下來(lái)時(shí)實(shí)例運(yùn)行階段的2個(gè)鉤子
        beforeUpdate() {  // 這時(shí)候,頁(yè)面還沒(méi)有被更新,但數(shù)據(jù)已經(jīng)被更新了
            console.log('界面中的元素是:' + document.getElementById('h3').innerText); // 界面中的元素是:ok
            console.log('data中的msg此時(shí)是' + this.msg); // data中的msg此時(shí)是no
            // 由上可見(jiàn),如果data不更新,那么該鉤子也不會(huì)執(zhí)行,并且當(dāng)鉤子執(zhí)行時(shí),頁(yè)面上綁定的數(shù)據(jù)還沒(méi)有被渲染出來(lái)。
        },
        updated() {
            console.log('界面中的元素是:' + document.getElementById('h3').innerText); // 界面中的元素是:no
            console.log('data中的msg此時(shí)是' + this.msg); // data中的msg此時(shí)是no
            // 可見(jiàn),在內(nèi)存中的虛擬DOM樹(shù)被更新并被重新渲染到視圖之后,updated鉤子才被執(zhí)行,此時(shí)視圖綁定的數(shù)據(jù)與data中是一樣的。
        }
    })

</script>
</html>

生命周期鉤子

生命周期鉤子就是生命周期事件的別名罷了,Vue實(shí)例創(chuàng)建到銷毀的生命周期中存在以下生命周期鉤子。

1. beforeCreate

· 類型:Function
· 在實(shí)例初始化之后,數(shù)據(jù)觀測(cè)(data observer)和event/watcher事件配置之前被調(diào)用。

2. created

· 類型:Function
· 在實(shí)例創(chuàng)建完成后被立即調(diào)用。在這一步,實(shí)例已完成以下配置:數(shù)據(jù)觀測(cè)(data observer),屬性和方法的運(yùn)算,watch/event事件回調(diào)。然而掛載階段還沒(méi)開(kāi)始,$el屬性目前尚不可用。

3. beforeMount

· 類型:Function
· 在掛載開(kāi)始之前被調(diào)用,相關(guān)的render函數(shù)首次被調(diào)用。
該鉤子在服務(wù)器端渲染期間不被調(diào)用

mounted

· 類型:Function
· 實(shí)例被掛載后調(diào)用,這是el·被新創(chuàng)建的vm.el`替換了。如果根實(shí)例被掛載到了一個(gè)文檔內(nèi)的元素上,當(dāng)`mounted`被調(diào)用時(shí)`vm.el也在文檔內(nèi)。 需要注意的是,mounted不會(huì)保證所有的子組件也都一起被加載。如果你希望等到整個(gè)視圖都渲染完畢,可以在mounted內(nèi)部使用vm.$nextTick`:

mounted: function () {
  this.$nextTick(function () {
    // 此處代碼只會(huì)等到整個(gè)視圖都渲染完畢后才執(zhí)行
  })
}

該鉤子在服務(wù)器端渲染期間不會(huì)被調(diào)用

beforeUpdated

· 類型:Function
· 數(shù)據(jù)更新時(shí)調(diào)用,發(fā)生在虛擬DOM打補(bǔ)丁之前。這里更適合在更新之前訪問(wèn)現(xiàn)有的DOM,比如手動(dòng)移除已添加的事件監(jiān)聽(tīng)器。
該鉤子在服務(wù)器端渲染期間不會(huì)被調(diào)用,因?yàn)橹挥谐醮武秩緯?huì)在服務(wù)器端進(jìn)行。

updated

· 類型:Function
· 由于數(shù)據(jù)更改導(dǎo)致的虛擬DOM重新渲染和打補(bǔ)丁,在這之后會(huì)調(diào)用該鉤子。
當(dāng)這個(gè)鉤子被調(diào)用時(shí),組件DOM已經(jīng)更新,所以你現(xiàn)在可以執(zhí)行依賴于DOM的操作。然而在大多數(shù)情況下,你應(yīng)該避免在此期間更改狀態(tài)。如果要相應(yīng)狀態(tài)改變,通常最好使用計(jì)算屬性或watcher來(lái)取而代之。
注意updated不會(huì)保證所有的子組件也都一起被重繪。如果你希望等到整個(gè)視圖都重繪完畢,可以在updated里使用vm.$nextTick

updated: function () {
  this.$nextTick(function () {
    // 此處的代碼只會(huì)在整個(gè)視圖都重繪完畢后才執(zhí)行
  })
}

該鉤子在服務(wù)器端渲染期間不會(huì)被調(diào)用

actived

· 類型:Function
· 被keep-alive緩存的組件激活時(shí)調(diào)用。
該鉤子在服務(wù)器端渲染期間不被調(diào)用

deactivated

· 類型:Function
· 被keep-alive緩存的組件停用時(shí)調(diào)用。
該鉤子在服務(wù)器端渲染期間不被調(diào)用

beforeDestroy

· 類型:Function
· 實(shí)例銷毀之前調(diào)用,在這一步實(shí)例仍然完全可用。
該鉤子在服務(wù)器端渲染期間不被調(diào)用

destroyed

· 類型:Function
· 實(shí)例銷毀后調(diào)用,該鉤子被調(diào)用后,對(duì)應(yīng)Vue實(shí)例的所有指令都被解綁,所有的事件監(jiān)聽(tīng)器被移除,所有的子實(shí)例也都被銷毀。
該鉤子在服務(wù)器端不被調(diào)用

errorCaptured

· 類型:(err: Error, vm: Component, info: string) => ?boolean
· 當(dāng)捕獲一個(gè)來(lái)自子孫組件的錯(cuò)誤時(shí)被調(diào)用。此鉤子會(huì)收到三個(gè)參數(shù):錯(cuò)誤對(duì)象、發(fā)生錯(cuò)誤的組件實(shí)例以及一個(gè)包含錯(cuò)誤來(lái)源信息的字符串。此鉤子可以返回false以阻止該錯(cuò)誤繼續(xù)向上傳播。
你可以在此鉤子中修改組件的狀態(tài)。因此在捕獲錯(cuò)誤時(shí),在模板或渲染函數(shù)中有一個(gè)條件判斷來(lái)繞過(guò)其他內(nèi)容就很重要;不然該組件可能會(huì)進(jìn)入一個(gè)無(wú)限的渲染循環(huán)。
錯(cuò)誤傳播規(guī)則
· 默認(rèn)情況下,如果全局的config.errorHandler被定義,所有的錯(cuò)誤仍會(huì)發(fā)送它,因此這些錯(cuò)誤仍然會(huì)向單一的分析服務(wù)的地方進(jìn)行匯報(bào)。
· 如果一個(gè)組件的繼承或父級(jí)從屬鏈路中存在多個(gè)errorCaptured鉤子,則它們將會(huì)被相同的錯(cuò)誤逐個(gè)喚起。
· 如果此errorCaptured鉤子自身拋出了一個(gè)錯(cuò)誤,則這個(gè)新錯(cuò)誤和原本被捕獲的錯(cuò)誤都會(huì)發(fā)送給全局的config.errorHandler
· 一個(gè)errorCaptured鉤子能夠返回false以阻止錯(cuò)誤繼續(xù)向上傳播。本質(zhì)上是說(shuō)“這個(gè)錯(cuò)誤已經(jīng)被搞定了且應(yīng)該被忽略”,它會(huì)阻止其它任何被這個(gè)錯(cuò)誤喚起的errorCaptured鉤子和全局的config.errorHandler。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容