Vue筆記(Vue生命周期 11個(gè)鉤子)

Vue實(shí)例有一個(gè)完整的生命周期江解,也就是說從開始創(chuàng)建、初始化數(shù)據(jù)徙歼、編譯模板犁河、掛在DOM、渲染-更新-渲染魄梯、卸載等一系列過程桨螺,我們稱為Vue 實(shí)例的生命周期(鉤子函數(shù))

19669186-4c417cbdf6c30add.png

附上網(wǎng)上找的一張圖解釋
當(dāng)我們 new vue 的時(shí)候,這些函數(shù)就會(huì)自動(dòng)執(zhí)行

生命周期鉤子的11個(gè)階段:

創(chuàng)建:
beforeCreate -- 數(shù)據(jù)初始化前
created -- 數(shù)據(jù)初始化之后
beforeMount -- 數(shù)據(jù)準(zhǔn)備渲染
Mounted -- 數(shù)據(jù)渲染完成
運(yùn)行:
beforeUpdata -- 數(shù)據(jù)更新前
updated -- 數(shù)據(jù)更新
銷毀:
beforeDestroy -- 結(jié)束之前執(zhí)行
destroyed -- 執(zhí)行結(jié)束
緩存:
activated -- 組件激活時(shí)執(zhí)行
deactivated -- 組件停用時(shí)執(zhí)行
錯(cuò)誤處理
errorCaptured -- 錯(cuò)誤處理機(jī)制


構(gòu)建vue實(shí)例

            var vm = new Vue({
                el:"#app",
                data:{
                    circle:"生命周期"
                },

beforeCreate -- 數(shù)據(jù)初始化前

在實(shí)例初始化之后,數(shù)據(jù)觀測(cè)和event|watcher事件配置之前使用,
這個(gè)時(shí)期,this變量還不能使用,在data下面的數(shù)據(jù)和methods下面的方法,watcher中的事件都獲取不到酿秸。

可以在這里加一個(gè)loading事件,在實(shí)例加載的時(shí)候觸

    beforeCreate(){
        console.group("beforeCreate 創(chuàng)建狀態(tài),初始化前");
        console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
        console.log(this.$el);//undefined
        console.log("%c%s","color:skyblue","el:"+this.$el);//el:undefined
        console.log("%c%s","color:green","data:"+this.$data);//data:undefined
        console.log("%c%s","color:blue","message:"+this.circle);//message:undefined
    },
image.png

created -- 數(shù)據(jù)初始化之后

實(shí)例已經(jīng)創(chuàng)建完成之后被調(diào)用灭翔,在這一步,實(shí)例已經(jīng)完成以下的配置辣苏,數(shù)據(jù)觀測(cè)缠局,屬性和方法的運(yùn)算,event|watcher事件回調(diào);但是,掛載階段還沒有開始,$el屬性還不可見,這個(gè)時(shí)候可以操作vue實(shí)例中的數(shù)據(jù)和各種方法.但是還不能對(duì)DOM節(jié)點(diǎn)進(jìn)行操作

初始化完成時(shí)的事件寫在這里考润,比如在這里結(jié)束loading事件,異步請(qǐng)求也可以在這里調(diào)用

    created(){
        console.group("created 創(chuàng)建狀態(tài),初始化后");
        console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
        console.log("%c%s","color:skyblue","el:"+this.$el);//el:undefined
        console.log(this.$el);//undefined
        console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
        console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期
    },
image.png

beforeMount -- 數(shù)據(jù)準(zhǔn)備渲染

在掛載開始之前被調(diào)用读处,相關(guān)的render函數(shù)首次被調(diào)用

這個(gè)時(shí)候可以獲取到DOM節(jié)點(diǎn),但還不能進(jìn)行操作

    beforeMount(){
        console.group("beforeMount 創(chuàng)建狀態(tài),準(zhǔn)備渲染");
        console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
        console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement]
        console.log(this.$el);//<div id="app" >...</div>
        console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
        console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期
    },
image.png

Mounted -- 數(shù)據(jù)渲染完成

el 被新創(chuàng)建的vm.$el替換并掛載到實(shí)例上去之后調(diào)用這個(gè)鉤子糊治,如果root實(shí)例掛載了一個(gè)文檔內(nèi)元素,當(dāng)Mounted被調(diào)用時(shí),vm. $el也在文檔中罚舱。

掛載完畢井辜,DOM節(jié)點(diǎn)被渲染到文檔中,DOM操作可以正常進(jìn)行

    mounted(){
        console.group("mounted 創(chuàng)建狀態(tài),渲染完成");
        console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
        console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement]
        console.log(this.$el);//<div id="app" >...</div>
        console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
        console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期
    },
image.png

beforeUpdata -- 數(shù)據(jù)更新前

數(shù)據(jù)更新時(shí)調(diào)用管闷,發(fā)生在虛擬 DOM 打補(bǔ)丁之前粥脚。這里適合在更新之前訪問現(xiàn)有的 DOM,比如手動(dòng)移除已添加的事件監(jiān)聽器包个。

這里獲取到data的數(shù)據(jù)是已經(jīng)更新之后的數(shù)據(jù)刷允,但還沒渲染到文檔流中冤留,所以如果在這里獲取DOM節(jié)點(diǎn),得到的是未更新的數(shù)據(jù)树灶。

    beforeUpdata(){
        console.group("beforeUpdata 執(zhí)行狀態(tài),數(shù)據(jù)更新前");
        console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
        console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement]
        console.log(this.$el);//<div id="app" >...</div>
        console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
        console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期
    },

updated -- 數(shù)據(jù)更新

由于數(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取而代之诺祸。

數(shù)據(jù)更新已經(jīng)完成

    updated(){
        console.group("updated 執(zhí)行狀態(tài),數(shù)據(jù)更新");
        console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
        console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement]
        console.log(this.$el);//<div id="app" >...</div>
        console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
        console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期
    },

在這里綁定了一個(gè)按鈕携悯,改變數(shù)據(jù)
更新前 beforeUpdata:

image.png

點(diǎn)擊更新后 updated :

image.png

image.png

beforeDestroy -- 結(jié)束之前執(zhí)行

在實(shí)例銷毀之前調(diào)用,實(shí)例仍然完全可用序臂,這一步還可以用this來獲取實(shí)例蚌卤,一般在這一步做一些重置的操作,比如清除掉組件中的定時(shí)器 和 監(jiān)聽的dom事件

beforeDestroy(){
    console.group("beforeDestroy 銷毀狀態(tài),銷毀前執(zhí)行");
    console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
    console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement]
    console.log(this.$el);
    console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
    console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期
},
image.png

destroyed -- 執(zhí)行結(jié)束

在實(shí)例銷毀之后調(diào)用奥秆,調(diào)用后逊彭,所以的事件監(jiān)聽器會(huì)被移出,所有的子實(shí)例也會(huì)被銷毀构订,該鉤子在服務(wù)器端渲染期間不被調(diào)用

destroyed(){
    console.group("destroyed 銷毀狀態(tài),銷毀完成");
    console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
    console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement]
    console.log(this.$el);
    console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
    console.log("%c%s","color:blue","message:"+this.circle);//message:生命周期
},
image.png

activated 和 deactivated(組件激活時(shí)和停用時(shí)執(zhí)行)

這兩個(gè)鉤子需要配合配合<keep-alive><keep-alive/>來使用
keep-alive的作用會(huì)緩存不活動(dòng)的組件實(shí)例侮叮,而不是銷毀它們。當(dāng)組件在<keep-alive>內(nèi)被切換悼瘾,activateddeactivated這兩個(gè)生命周期鉤子函數(shù)將會(huì)被對(duì)應(yīng)執(zhí)行囊榜。

在這里我搭建了一個(gè)腳手架,新建2個(gè)子組件亥宿,1個(gè)父組件

子組件A內(nèi)容
<template>
    <div>
        <div>componentA</div>
        <button @click="show=!show" >componentA事件</button>
        <div v-if='show'>componentA-2</div>
        <div v-else>componentA-1</div>
    </div>
</template>
<script>
    export default {
        name: 'componentA',
        comments: {},
        data() {
            return {
                show: true,
                circle:'生命周期'
            }
        },
        activated() {
            console.group("activated 組件激活時(shí)執(zhí)行 ");
            console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
            console.log(this.$el);//<div id="app" >...</div>
            console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement]
            console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
            console.log("%c%s","color:blue","message:"+this.circle);//message:undefined
        },      
        deactivated() {
            console.group("deactivated 組件停用時(shí)執(zhí)行");
            console.log("%c%s","color:pink",this);//this指向vue的實(shí)例
            console.log(this.$el);//<div id="app" >...</div>
            console.log("%c%s","color:skyblue","el:"+this.$el);//el:[object HTMLDivElement]
            console.log("%c%s","color:green","data:"+this.$data);//data:[object Object]
            console.log("%c%s","color:blue","message:"+this.circle);//message:undefined
        }
    }
</script>
<style>
</style>
子組件B內(nèi)容
<template>
    <div>
        <div>componentB</div>
    </div>
</template>
<script>
    export default {
        name: 'componentB',
        compnents: {},
        data() {
            return {}
        }
    }
</script>
<style>
</style>
父組件內(nèi)容
<template>
    <div id="box">

        <button @click="active='componentA'">componentA</button>
        <button @click="active='componentB'">componentB</button>
        
        <keep-alive>
            <component :is='active' ></component>
        </keep-alive>
        
    </div>
</template>
<script>
    import Vue from 'vue'
    import componentA from '@/components/componentA'
    import componentB from '@/components/componentB'

    export default{
        
        components:{
            componentA,
            componentB
        },
        
        data(){
            return{
                active:'componentB'
            }
        }
    }
</script>
<style>
</style>

輸出

SDGIF_Rusult_2.gif

這里看到當(dāng)A組件被點(diǎn)擊激活時(shí)就觸發(fā)activated鉤子卸勺,點(diǎn)擊B組件開啟A組件關(guān)閉時(shí)deactivated鉤子就觸發(fā)執(zhí)行。

這里也能看出在keep-alive 里A組件的數(shù)據(jù)也被緩存起來烫扼,第二次觸發(fā)的時(shí)候組件狀態(tài)沒有被重新改變


errorCaptured -- 錯(cuò)誤處理機(jī)制

當(dāng)捕獲一個(gè)來自子孫組件的錯(cuò)誤時(shí)被調(diào)用曙求。此鉤子會(huì)收到三個(gè)參數(shù):錯(cuò)誤對(duì)象、發(fā)生錯(cuò)誤的組件實(shí)例以及一個(gè)包含錯(cuò)誤來源信息的字符串映企。此鉤子可以返回 false 以阻止該錯(cuò)誤繼續(xù)向上傳播

1.默認(rèn)情況下悟狱,如果全局的 config.errorHandler定義,所有的錯(cuò)誤仍會(huì)發(fā)送它堰氓,因此這些錯(cuò)誤仍然會(huì)向單一的分析服務(wù)的地方進(jìn)行匯報(bào)
如果一個(gè)組件的繼承或父級(jí)從屬鏈路中存在多個(gè) errorCaptured 鉤子挤渐,則它們將會(huì)被相同的錯(cuò)誤逐個(gè)喚起。
2.如果此 errorCaptured 鉤子自身拋出了一個(gè)錯(cuò)誤双絮,則這個(gè)新錯(cuò)誤和原本被捕獲的錯(cuò)誤都會(huì)發(fā)送給全局的 config.errorHandler浴麻,不能捕獲異步promise內(nèi)部拋出的錯(cuò)誤和自身的錯(cuò)誤
3.一個(gè) errorCaptured 鉤子能夠返回 false 以阻止錯(cuò)誤繼續(xù)向上傳播得问。本質(zhì)上是說“這個(gè)錯(cuò)誤已經(jīng)被搞定了且應(yīng)該被忽略”。它會(huì)阻止其它任何會(huì)被這個(gè)錯(cuò)誤喚起的 errorCaptured 鉤子和全局的 config.errorHandler

在全局組件main.js中使用

import Vue from 'vue'//引入Vue框架

import router from './router'//引入路由

Vue.config.errorHandler = function (err, vm, info) {
      // #處理錯(cuò)誤信息, 進(jìn)行錯(cuò)誤上報(bào)
      // #err錯(cuò)誤對(duì)象
      // #vm Vue實(shí)例
      // #`info` 是 Vue 特定的錯(cuò)誤信息白胀,比如錯(cuò)誤所在的生命周期鉤子
      // #只在 2.2.0+ 可用
    console.log("%c%s","color:red","#err錯(cuò)誤對(duì)象:",err)
    console.log("%c%s","color:blue","#vm Vue實(shí)例:",vm)
    console.log("%c%s","color:green","#`info` 是 Vue 特定的錯(cuò)誤信息椭赋,比如錯(cuò)誤所在的生命周期鉤子:",info)
}   

然后在子組件中隨意寫入一個(gè)錯(cuò)誤的信息

        mounted () {
            a // 直接定義一個(gè)錯(cuò)誤的變量 a
        },

輸出

image.png

當(dāng)這個(gè)鉤子檢測(cè)到組件中發(fā)生錯(cuò)誤時(shí)就被調(diào)用。通過err, vm, info這3個(gè)參數(shù)輸出
#err錯(cuò)誤對(duì)象
#vm Vue實(shí)例
#info 是 Vue 特定的錯(cuò)誤信息或杠,比如錯(cuò)誤所在的生命周期鉤子


總結(jié)一下:

beforecreate:實(shí)例剛剛創(chuàng)建出來哪怔,data等屬性方法都不能獲取,loading事件可以放在這里向抢。
created:實(shí)例初始化完成认境,data等屬性方法也初始化完成,但還沒有開始編譯挟鸠,可以在這里結(jié)束loading叉信,可以發(fā)送請(qǐng)求,拿數(shù)據(jù)艘希。硼身!注意一下,因?yàn)樵谶@里還沒有渲染頁面覆享,如果獲取的數(shù)據(jù)過多佳遂,會(huì)造成有一段空白頁面的延遲。
beforemount :屬性方法等已經(jīng)編譯完成撒顿,但還沒掛載丑罪。
mounted:這里所有的屬性方法已經(jīng)完成掛載。
beforeUpdate:這個(gè)獲取的數(shù)據(jù)是最新的值凤壁,但dom還是舊值
updated:dom更新完成吩屹。
beforedestroy:消亡前,用來清除定時(shí)器
destroy:已消亡拧抖,也能用來清除定時(shí)器
destroyed:實(shí)例完全銷毀
activated:可以用來初始化數(shù)據(jù)
deactivated:在緩存里能用來代替beforedestroydestroy
errorCaptured :能快速找到報(bào)錯(cuò)的組件位置煤搜,還能解決滿屏紅等視覺沖擊

問題:
如果當(dāng)在子組件里寫了一個(gè)定時(shí)器,子組件被銷毀后唧席,定時(shí)器還是會(huì)繼續(xù)執(zhí)行擦盾,所以要使用beforedestroydestroyed,組件銷毀后袱吆,清除定時(shí)器。

<keep-alive> 包裹動(dòng)態(tài)組件時(shí)距淫,會(huì)緩存不活動(dòng)的組件實(shí)例绞绒,而不是銷毀它們,所以在<keep-alive>中的所有組件不會(huì)觸發(fā)beforedestroydestroyed 這兩個(gè)鉤子函數(shù)

關(guān)于createdactivated 的區(qū)別
created 是頁面初始化時(shí)才觸發(fā)的函數(shù)榕暇,vue的優(yōu)勢(shì)在于不需要刷新或重啟頁面蓬衡,所以created只會(huì)觸發(fā)一次喻杈。而activated 是只要頁面組件被激活就會(huì)執(zhí)行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市狰晚,隨后出現(xiàn)的幾起案子筒饰,更是在濱河造成了極大的恐慌,老刑警劉巖壁晒,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓷们,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡秒咐,警方通過查閱死者的電腦和手機(jī)谬晕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來携取,“玉大人攒钳,你說我怎么就攤上這事±鬃蹋” “怎么了不撑?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)晤斩。 經(jīng)常有香客問我焕檬,道長(zhǎng),這世上最難降的妖魔是什么尸昧? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任揩页,我火速辦了婚禮,結(jié)果婚禮上烹俗,老公的妹妹穿的比我還像新娘爆侣。我一直安慰自己,他們只是感情好幢妄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布兔仰。 她就那樣靜靜地躺著,像睡著了一般蕉鸳。 火紅的嫁衣襯著肌膚如雪乎赴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天潮尝,我揣著相機(jī)與錄音榕吼,去河邊找鬼。 笑死勉失,一個(gè)胖子當(dāng)著我的面吹牛羹蚣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乱凿,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼顽素,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼咽弦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起胁出,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤型型,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后全蝶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闹蒜,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年裸诽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嫂用。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丈冬,死狀恐怖嘱函,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情埂蕊,我是刑警寧澤往弓,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站蓄氧,受9級(jí)特大地震影響函似,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喉童,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一撇寞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧堂氯,春花似錦蔑担、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晶框,卻和暖如春排抬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背授段。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國打工蹲蒲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侵贵。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓届搁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咖祭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351