vue的生命週期詳解:從入門到精通

Vue生命週期

在學習vue的過程中,vue的生命週期可謂是重中之重,必學的一部分。
每個 Vue 實例在被創建時都要經過一系列的初始化過程,例如,需要設置數據監聽、編譯模板、將實例掛載到 DOM 並在數據變化時更新 DOM 等。同時在這個過程中也會運行一些叫做生命週期鉤子的函數,這給了用戶在不同階段添加自己的代碼的機會。下面這張圖想必大家都不陌生

生命週期圖示

在這裏插入圖片描述
解釋:首先創建一個vue實例,進行第一次初始化操作,這次初始化僅僅是初始化自己的事件和自己的生命週期,初始化完成之後,開始第二次初始化,此時會將datacomputedmethods等等的數據觀測 (data observer),屬性和方法的運算,event/watch 事件回調進行初始化注入,完成之後,會檢查是否指定了el選項,如果指定了,或沒用指定但調用了vm.$mout("el")時,繼續查看是否指定了template模板,如果沒用指定,則把外部的HTML作爲template編譯,如果指定了,則將template渲染到render函數中(當然我們也可以不使用template,直接使用render函數創建模板),然後創建vm.$el,替換掉el,此時便已經掛載完畢了,如果數據改變,則虛擬DOM重新渲染,並應用更新,當調用銷燬方法是,解除綁定,銷燬子組件及事件監聽器。

生命週期鉤子

所有的生命週期鉤子自動綁定 this 上下文到實例中,因此你可以訪問數據,對屬性和方法進行運算,所以,不要在鉤子函數定義的時候使用箭頭函數,箭頭函數沒用 this,可能會報錯 Uncaught TypeError: Cannot read property of undefined
在這裏插入圖片描述

我在這下面依次介紹着8個生命週期鉤子!

  • beforeCreate

    在實例初始化之後,數據觀測 (data observer) 和 event/watch 事件配置之前被調用。

<div id="app">
   {{ name }}
</div>
const vm = new Vue({
    el:"#app",
    data:{
        name:"monk"
    },
    beforeCreate(){
        console.log(this.name);
        console.log(this.handleFunction)
        console.log("--beforeCreate--")
    },
    methods: {
        handleFunction(){
            console.log("我是一個方法!");
        }
    },
    watch: {
        name:{
            handler(){
                console.log("我已經開始監聽偵聽name屬性啦");
            },
            immediate:true
        }
    },
})

打印順序:在實例初始化之後,數據觀測 (data observer) 和 event/watch 事件配置之前被調用。

undefined
undefined
--beforeCreate--
我已經開始監聽偵聽name屬性啦
  • created

    在實例創建完成後被立即調用。在這一步,實例已完成以下的配置:數據觀測 (data observer),屬性和方法的運算,event/watch 事件回調。

    如果要在第一時間調用methods中的方法,或者操作data中的數據,可在此鉤子中進行操作。需要注意的是,執行此鉤子時,掛載階段還未開始,$el 屬性目前不可見。此時,可以進行數據請求,將請求回來的值賦值給data中的數據。

<div id="app">
  {{ name }}
</div>
const vm = new Vue({
    el:"#app",
    data:{
        name:"monk"
    },
    created(){
        console.log(this.name);
        console.log(this.handleFunction)
        console.log(this.$el);
        console.log('----------created-------');
    },
    methods: {
        handleFunction(){
            console.log("我是一個方法!");
        }
    },
    watch: {
        name:{
            handler(){
                console.log("我已經開始監聽偵聽name屬性啦");
            },
            immediate:true
        }
    },
})

打印順序:此時已完成以下的配置:數據觀測 (data observer),屬性和方法的運算,watch/event 事件回調。

我已經開始監聽偵聽name屬性啦
monk
ƒ handleFunction(){console.log("我是一個方法!");}
undefined
----------created-------
  • beforeMount

    在掛載開始之前被調用,此時模板已經編譯完成,只是未將生成的模板替換el對應的元素。在此鉤子函數中,可以獲取到模板最初始的狀態。此時,可以拿到vm.$el,只不過爲舊模板

const vm = new Vue({
  el: '#app',
  beforeMount () {
    console.log(this.$el);
  }
})

打印結果:可以拿到vm.$el,只不過爲舊模板

<div id="app">{{ name }}</div>
  • mounted

    el 被新創建的 vm.$el 替換,並掛載到實例上去之後調用該鉤子。在該鉤子函數中的vm.$el爲新模板。執行完該鉤子函數後,代表實例已經被完全創建好。如果要在第一時間,操作頁面上的dom節點時,可以在此鉤子函數中操作

const vm = new Vue({
  el: '#app',
  mounted () {
    console.log(this.$el);
  }
})

打印結果:此時的模板已經是新模板

<div id="app">monk</div>
  • beforeUpdate

    數據更新時調用,發生在虛擬 DOM 打補丁之前。此時數據已經更新,但是DOM還未更新

<div id="app">
  {{ name }}
</div>
const vm = new Vue({
    el:"#app",
    data:{
        name:"monk"
    },
    beforeUpdate(){
        console.log(this.name);
        console.log(this.$el);
    }
})
vm.name = "young monk"

打印結果:此時數據和虛擬dom已經更新,但真實Dom未更新

young monk
<div id="app">young monk</div>
  • updated

    數據更改導致DOM重新渲染後,會執行該鉤子函數。此時數據和dom同步。感覺不需要舉例,嘿嘿嘿

  • beforeDestroy

    實例銷燬之前調用。在這一步,實例仍然完全可用。可以在該鉤子函數中,清除定時器。

<div id="app">
  {{ name }}
</div>
const vm = new Vue({
    el:"#app",
    data:{
        name:"monk",
        timer:null
    },
    created(){
        this.timer = setInterval(()=>{
            console.log("定時器執行!!!")
        },1000)
    },
    beforeDestroy() {
        clearInterval(this.timer)  
    }
})

打印結果:實例創建後會一直執行定時器中內容,直到執行銷燬函數時 vm.$destroy(),消除定時器,結束執行

  • destroyed

    Vue 實例銷燬後調用。調用後,Vue 實例指示的所有東西都會解綁定,所有的事件監聽器會被移除。

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