[Vue 牛刀小試]:第七章 - Vue 實例的生命週期

 1、前言

   在以前的 Vue 學習中,咱們在使用 Vue 時,都會建立一個 Vue 的實例,而每一個 Vue 實例在被建立時都要通過一系列的初始化過程。例如,須要設置數據監聽、編譯模板、將實例掛載到 DOM 並在數據變化時更新 DOM 等。在這個過程當中,Vue 會運行一些生命週期鉤子函數,而咱們則能夠在鉤子函數中編寫一些自定義方法,用以在 Vue 的整個生命週期中某些階段實現咱們特殊需求。那麼,本章,咱們就來了解 Vue 實例的生命週期鉤子函數。html

  學習系列目錄地址:http://www.javashuo.com/article/p-bzzucmub-ba.htmlvue

  倉儲地址:https://github.com/Lanesra712/VueTrial/blob/master/Chapter01-Rookie/hocks.htmlgit

 2、乾貨合集

  在咱們使用 Vue 的時候,都會先建立一個 Vue 實例,這個實例不只是咱們掛載 Vue 框架的入口,也是 MVVM 思想中的 VM(ViewModel)。在咱們使用 Vue 的整個過程當中,歸根結底都是在對這個 Vue 實例進行操做。所以,只有當咱們瞭解 Vue 實例的生命週期以後,才能夠更好的實現咱們的業務邏輯。github

  在 Vue 官網的這張生命週期圖示中,咱們能夠看到整個生命週期中包含了8個鉤子函數:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。從字面意思咱們就能夠清楚的看出來,這8個鉤子函數兩個一組,分別對應於 Vue 實例的建立、掛載、更新、銷燬,接下來,咱們就根據這四個階段,解釋 Vue 實例各個階段中的鉤子函數的做用。segmentfault

  一、beforeCreate & created

  在咱們經過 new Vue() 建立了一個 Vue 實例以後,會執行 init 方法,此時只會初始化 Vue 實例所包含的一些默認的事件與生命週期函數,在這個實例還未被徹底建立以前,則會執行咱們的 beforeCreate 鉤子函數。瀏覽器

  在下面的例子中,咱們在實例化 Vue 對象時,自定義了一個 message 屬性,同時設定了一個 show 方法,如今咱們來看看當實例並無徹底被建立以前,是否可以獲取到咱們自定義的屬性與方法。app

<div id="app">
    {{message}}
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Hello World!'
        },
        methods: {
            show() {
                console.log('執行了 show 方法');
            }
        },
        beforeCreate() {
            console.log(`Vue 實例掛載對象 el:${this.$el}`)
            console.log(`Vue 實例的 data 對象:${this.$data}`)
            console.log(`Vue 實例的 message 屬性值:${this.message}`)
            console.log(`Vue 實例的 methods 對象:${this.$options.methods}`)
            this.show();
        }
    })
</script>

 

  從瀏覽器的控制檯中咱們能夠看到,此時,Vue 實例中的 data、methods 對象,或是咱們定義的 Vue 實例的掛載點元素,在 beforeCreated 生命週期鉤子函數執行時,都沒有進行了初始化。框架

  當 beforeCreated 鉤子函數執行完成後,Vue 實例已經初始化完成,此時將要執行生命週期中的 created 鉤子函數來監聽咱們對於數據的更改或是監聽事件。函數

<div id="app">
    {{message}}
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Hello World!'
        },
        methods: {
            show() {
                console.log('執行了 show 方法');
            }
        },
        created() {
            console.log(`Vue 實例掛載對象 el:${this.$el}`)
            console.log(`Vue 實例的 data 對象:${this.$data}`)
            console.log(`Vue 實例的 message 屬性值:${this.message}`)
            console.log(`Vue 實例的 methods 對象:${this.$options.methods}`)
            this.show();
        }
    })
</script>

 

  

  從瀏覽器控制檯打印出的信息能夠看出,在執行 created 鉤子函數的過程當中,對於自定義的屬性 message、自定義的方法 show 已經初始化完成,此時,整個 Vue 實例已經初始化完成。可是,對於咱們的 Vue 實例的掛載點元素尚未進行初始化。也就是說,當執行完 created 以後,Vue 實例與 View(視圖層)之間依舊是處於隔離的狀態,初始化完成的 Vue 實例也依舊沒有與 DOM 進行綁定。post

  二、beforeMount & mounted

  當 Vue 實例執行完 beforeCreated、created 鉤子函數以後,Vue 實例已經初始化完成,而 Vue 實例並無掛載到頁面的 DOM 上。在掛載到頁面 DOM 元素以前,則須要執行 beforeMount 鉤子函數將咱們的實例綁定到模板上進行編譯渲染。

<div id="app">
    <h3 id="h3">{{message}}</h3>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Hello World!'
        },
        methods: {
            show() {
                console.log('執行了 show 方法');
            }
        },
        beforeMount() {
            console.log(document.getElementById('h3').innerText)
        }
    })
</script>

  從控制檯輸出的信息能夠看到,當執行到 beforeMount 鉤子函數時,已經將模板編譯完成,可是還沒有掛載到頁面上去。

  當把編譯完成的模板掛載到頁面上時,則須要執行 mounted 鉤子函數,在這個階段,用戶就能夠看到已經渲染好的頁面。

<div id="app">
    <h3 id="h3">{{message}}</h3>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Hello World!'
        },
        methods: {
            show() {
                console.log('執行了 show 方法');
            }
        },
        mounted() {
            console.log(document.getElementById('h3').innerText)
        }
    })
</script>

 

  這裏咱們能夠看到,已經能夠獲取到差值表達式的值,即當執行到 mounted 鉤子函數時,頁面已經渲染完成了。    

  從上面的例子中能夠看出,mounted 是建立 Vue 實例過程當中的最後一個生命週期鉤子函數,當執行完 mounted 鉤子函數以後,實例已經被完成建立好,並已經渲染到頁面中,此時,若是咱們不對實例進行任何的操做的話,Vue 實例則不會執行 新的生命週期鉤子函數。

  3、beforeUpdate & updated

  在執行完了 mounted 鉤子函數以後,Vue 實例實際已經脫離了實例的建立階段,進入實例的運行階段。此時,當咱們對實例的 data 進行修改時,則會觸發 beforeUpdate、updated 這兩個鉤子函數。

<div id="app">
    <h3 id="h3">{{message}}</h3>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Hello World!'
        },
        methods: {
            show() {
                console.log('執行了 show 方法');
            }
        },
        beforeUpdate() {
            console.log(`頁面上的數據:${document.getElementById('h3').innerText}`)
            console.log(`data 中的 message 數據:${this.message}`)
        }
    })
</script>

 

  咱們能夠看到,當咱們對 data 中的 message 屬性進行修改時,在執行 beforeUpdate 鉤子函數時,頁面上的數據仍是舊的數據,而 data 中 message 屬性已經將值修改爲了最新的值(這裏頁面上顯示的爲修改後的數據則是由於執行了後面的鉤子函數,將修改後的數據同步渲染到了頁面上)。

  Vue 做爲一個具備數據雙向綁定特性的框架,當咱們實時修改了頁面元素的值以後,確定但願頁面能夠同步變動數據。而在執行 beforeUpdate 鉤子函數以後,咱們已經在實例中修改了數據,如今只須要從新渲染到頁面就能夠了,這時候,則會執行 updated 鉤子函數。

<div id="app">
    <h3 id="h3">{{message}}</h3>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Hello World!'
        },
        methods: {
            show() {
                console.log('執行了 show 方法');
            }
        },
        updated() {
            console.log(`頁面上的數據:${document.getElementById('h3').innerText}`)
            console.log(`data 中的 message 數據:${this.message}`)
        }
    })
</script>

  

  從控制檯能夠看到,當 updated 鉤子函數執行的時候,頁面和 data 中的數據已經完成了同步,都顯示的是最新的數據。此時,整個頁面數據實時變動的操做也已經完成了。

  4、beforeDestroy & destroyed

  既然有 Vue 實例的建立,那麼在咱們不須要 Vue 實例的時候就須要將這個實例進行銷燬。而 beforeDestroy 以及 destroyed 鉤子函數則會幫咱們實現這一目的。

<div id="app">
    {{message}}
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Hello World!'
        },
        methods: {
            show() {
                console.log('執行了 show 方法');
            }
        },
        beforeDestroy() {
            console.log(`Vue 實例掛載對象 el:${this.$el}`)
            console.log(`Vue 實例的 data 對象:${this.$data}`)
            console.log(`Vue 實例的 message 屬性值:${this.message}`)
            console.log(`Vue 實例的 methods 對象:${this.$options.methods}`)
            this.show();
        },
        destroyed() {
            console.log(`Vue 實例掛載對象 el:${this.$el}`)
            console.log(`Vue 實例的 data 對象:${this.$data}`)
            console.log(`Vue 實例的 message 屬性值:${this.message}`)
            console.log(`Vue 實例的 methods 對象:${this.$options.methods}`)
            this.show();
        }
    })
</script>

 

   這裏,咱們手動銷燬 Vue 實例,從控制檯的輸出內容能夠看到,在 beforeDestroy 和 destroyed 鉤子函數執行中,咱們依舊能夠獲取到 Vue 實例的相關內容,但是,當咱們選擇更新 message 屬性的值時會發現,此時,頁面上顯示的值並無發生改變。原來,這裏的銷燬並不指代'抹去'這個 Vue 實例,而是表示將 Vue 實例與頁面的 DOM 元素進行'解綁'。

 3、總結

鉤子函數 描述
beforeCreate Vue 實例進行初始化,此時實例的各個組件尚未進行初始化完成,所以不能訪問到 data、computed、watch、methods 上的方法和數據,同時,Vue 實例的掛載點也沒有進行初始化
created Vue 實例初始化完成,此時能夠訪問 data、computed、watch、methods 上的方法和數據,可是依舊沒有進行 Vue 實例的掛載點初始化
beforeMount 將實例綁定到模板並進行渲染,但並不會將實例掛載到頁面上
mounted 將渲染好的模板綁定到頁面上,此時,Vue 實例已徹底建立好  
beforeUpdate 數據變動時調用,在實例數據更改以前執行任何應該發生的自定義邏輯或操做
updated 將 Vue 實例更新完成的數據從新渲染到內存中的虛擬 DOM 上,再將虛擬 DOM 應用到頁面上
beforeDestroy Vue 實例進入銷燬階段,此時實例上的 data、methods、過濾器、指令等等仍是處於可用的狀態,尚未真正執行銷燬的過程(解除與頁面 DOM 元素的綁定)
destroyed 實例被銷燬(解除與頁面 DOM 元素的綁定)

 4、參考

  一、詳解vue生命週期

  二、Vue2.0 探索之路——生命週期和鉤子函數的一些理解

  三、vue生命週期詳解

  四、vue生命週期探究(一)

  五、Vue生命週期深刻

  六、Vue 數據綁定和響應式原理

  七、Vue.js – lifecycle hooks, the layman’s overview

相關文章
相關標籤/搜索