完全搞定vue2.0生命週期鉤子函數問題

先給一張vue官網介紹生命週期的流程圖


lifecycle


官方給的東西確定很官方啦,不過單看一張圖對理解vue生命週期鉤子函數來講確定仍是有些難度的。不過各位小夥伴不要着急,本文 以簡單直接的實例 來對此圖進行理解。html


花10分鐘讀下去,相信我你必定會有一些收穫(僅僅指剛入門的小夥伴,做者也是一名剛入門的前端小白,大佬請見諒哈。😁😁)

Vue2.0的生命週期鉤子一共有10個分別簡單介紹以下:

  • beforeCreate:在實例初始化以後,數據觀測(data observer) 和 event/watcher 事件配置以前被調用。
  • created:實例已經建立完成以後被調用。在這一步,實例已完成如下的配置:數據監視(data observer),屬性和方法的運算, watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。
  • beforeMount:在掛載開始以前被調用相關的 render 函數首次被調用。
  • mounted:el 被新建立的 vm.el 替換,並掛載到實例上去以後調用此鉤子函數,若是 root 實例掛載了一個文檔內元素,當 mounted 被調用時 vm.el 也在文檔內。
  • beforeUpdate:數據更新時調用,發生在虛擬 DOM 從新渲染和打補丁以前。你能夠在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。
  • updated:因爲數據更改致使的虛擬 DOM 從新渲染和打補丁,在這以後會調用該鉤子。當這個鉤子被調用時,組件 DOM 已經更新,因此你如今能夠執行依賴於 DOM 的操做。
  • activated:keep-alive 組件激活時調用。
  • deactivated:keep-alive 組件停用時調用。
  • beforeDestroy:實例銷燬以前調用。在這一步,實例仍然徹底可用。
  • destroyed:Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。

來吧 上代碼!代碼直接能夠直接運行哦。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Vue-LifeClyle</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app" class="jing">
        <p>{{message}}</p>
        <keep-alive>
            <jh-component msg="2017年6月9日" v-if="show"></jh-component>
        </keep-alive>
    </div>
</body>
<script>
    var haohao = {
        template: '<div>from haohao: {{msg}}</div>',
        props: ['msg'],
        deactivated: function() {
            console.log('component deactivated!');
        },
        activated: function() {
            console.log('component activated');
        }
    };
    var app = new Vue({
        el: '#app',
        data: function() {
            return {
                message: 'jingjing',
                show: true //控制子組件是否顯示
            };
        },
        beforeCreate: function() {
            console.group('beforeCreate Vue實例建立前的狀態————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(state);
        },
        created: function() {
            console.group('created Vue實例建立完畢後狀態————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(state);
        },
        beforeMount: function() {
            console.group('beforeMount 掛載前狀態————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        mounted: function() {
            console.group('mounted 掛載後狀態————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        beforeUpdate: function() {
            console.group('beforeUpdate 更新前狀態————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
            console.log('beforeUpdate = ' + document.getElementsByTagName('p')[0].innerHTML);
        },
        updated: function() {
            console.group('updated 更新完成狀態————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
            console.log('Updated = ' + document.getElementsByTagName('p')[0].innerHTML);
        },
        beforeDestroy: function() {
            console.group('beforeDestroy 銷燬前狀態————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        destroyed: function() {
            console.group('destroyed 銷燬完成狀態————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        components: {
            'jh-component': haohao
        }
    });
</script>

<style>
    .jing {
        font-size: 50px;
        font-weight: bolder;
    }
</style>

</html>
複製代碼

代碼結構不難看懂

建立了一個 app 的Vue根實例,將其掛載到頁面 id 爲 app 的 Dom 元素上。 而後局部註冊了一個組件名爲 haohao 並在根實例中將其註冊,使其能夠在根實例的做用域中使用。 將子組件用 <keep-alive> 包裹,爲接下來的測試做準備。前端

關於<keep-alive>的問題就不在這裏做過多闡述了,你們能夠參考如下兩篇文章
    一、zhuanlan.zhihu.com/p/96740001
    二、www.jianshu.com/p/4b55d312d…vue

OK,到這裏咱們就能夠在谷歌瀏覽器中打開開發者工具,開始測試了!


一、beforeCreate 與 created

  • beforeCreate 執行時:datael均未初始化,值爲undefined
  • created 執行時:Vue 實例觀察的數據對象 data 已經配置好,已經能夠獲得app.message的值,但 Vue 實例使用的根 DOM 元素el還未初始化

二、beforeMount 與 mounted 和 activated 與 deactivated

  • beforeMount 執行時:datael均已經初始化,但從{{message}} 的展現狀況能夠看出此時 el 並無渲染數據,這裏就是應用的 Virtual DOM(虛擬Dom)技術,先把坑佔住了。到後面 mounted 掛載的時候再把值渲染上去npm

  • mounted 執行時:此時 el 已經渲染完成並掛載到實例上api

  • 咱們在控制檯看到component activated被打印出來了,說明子組件jh-component<keep-alive> 包裹,隨 el 的掛載而觸發了。瀏覽器

  • 而後咱們進行一些操做,在控制檯輸入 app.show = false咱們再來看看有什麼變化,測試結果以下圖:bash

  • 怎麼樣,有沒有發現什麼?😉😉😉
  • 由於咱們在這裏修改了data的值,因此會觸發beforeUpdateupdated鉤子函數,這裏先無論這兩個函數,咱們看到deactivated鉤子已經觸發,表示<keep-alive>已經停用。
    同時咱們的子組件也會消失。

三、beforeUpdate 和 updated

  • 咱們繼續在控制檯輸入app.message = 'haohao'
  • 咱們發現beforeUpdateupdated觸發時,el中的數據都已經渲染完成,但根據控制檯打印的信息beforeUpdate = jingjingupdated = haohao可知,只有當updated鉤子被調用時候,組件dom纔會被更新。


四、beforeDestroy 與 destroyed

  • 在控制檯輸入app.$destroy()就能夠將vue實例銷燬,可是咱們發現銷燬前和銷燬後的實例dom結構沒有任何改變,其實變化已經發生在了其餘地方。
  • 做者查了一下官方文檔描述:實例銷燬後,Vue實例指示的全部東西都會解除綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。

  • 咱們如今作最後一步操做就能證明上述結論。
  • 如今在控制檯輸入app.message = 'jingjing'發現結果以下圖:

  • 咱們改變了data中的message屬性,可是dom沒有任何響應。說明Vue實例指示的全部東西都已經解除了綁定。終於寫完了😄😄😄

寫在最後


做者只是一名前端大白(●—●) 此篇文章是第一篇,若是文中有錯誤請各位大佬諒解一下,指出錯誤就更好了,讓新人多一個學習的機會。😊😊app

此篇文章寫的很淺顯,若是有須要對內容有更深刻的學習,能夠看看大佬OBKoro寫的文章—— Vue的鉤子函數[路由導航守衛、keep-alive、生命週期鉤子]dom

但願看完的朋友能夠動動手點個贊再走哦,大家的支持是對我最大的鼓勵啊!!!


參考文檔

相關文章
相關標籤/搜索