包你理解---vue 的生命週期

vue生命週期流程圖:4張圖

圖片描述

clipboard.png
圖片描述html

clipboard.png

生命週期的解析和應用:

Vue 實例有一個完整的生命週期,也就是從開始建立、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,咱們稱這是 Vue 的生命週期。通俗說就是 Vue 實例從建立到銷燬的過程,就是生命週期。vue

  1. beforecreate :
    完成實例初始化,初始化非響應式變量
    this指向建立的實例;
    能夠在這加個loading事件;
    data computed watch methods上的方法和數據均不能訪問
  2. created
    實例建立完成
    完成數據(data props computed)的初始化 導入依賴項。
    可訪問data computed watch methods上的方法和數據
    未掛載DOM,不能訪問$el,$ref爲空數組
    可在這結束loading,還作一些初始化,實現函數自執行,
    能夠對data數據進行操做,可進行一些請求,請求不易過多,避免白屏時間太長。
    若在此階段進行的 DOM 操做必定要放在 Vue.nextTick() 的回調函數中
  3. berofeMount
    有了el,編譯了template|/outerHTML
    能找到對應的template,並編譯成render函數
  4. mounted
    完成建立vm.$el,和雙向綁定,
    完成掛載DOM 和渲染;可在mounted鉤子對掛載的dom進行操做
    即有了DOM 且完成了雙向綁定 可訪問DOM節點,$ref
    可在這發起後端請求,拿回數據,配合路由鉤子作一些事情;
    可對DOM 進行操做
  5. beforeUpdate
    數據更新以前
    可在更新前訪問現有的DOM,如手動移除添加的事件監聽器;
  6. updated :
    完成虛擬DOM的從新渲染和打補丁;
    組件DOM 已完成更新;
    可執行依賴的dom 操做
    注意:不要在此函數中操做數據,會陷入死循環的。
  7. activated:
    在使用vue-router時有時須要使用<keep-alive></keep-alive>來緩存組件狀態,這個時候created鉤子就不會被重複調用了,
    若是咱們的子組件須要在每次加載的時候進行某些操做,能夠使用activated鉤子觸發
  8. deactivated
    for keep-alive 組件被移除時使用
  9. beforeDestroy:
    在執行app.$destroy()以前
    可作一些刪除提示,如:你確認刪除XX嗎?
    可用於銷燬定時器,解綁全局時間 銷燬插件對象
  10. destroyed :vue-router

    當前組件已被刪除,銷燬監聽事件 組件 事件 子實例也被銷燬
    這時組件已經沒有了,你沒法操做裏面的任何東西了。

子父組件的生命週期
僅當子組件完成掛載後,父組件纔會掛載
當子組件完成掛載後,父組件會主動執行一次beforeUpdate/updated鉤子函數(僅首次)
父子組件在data變化中是分別監控的,可是在更新props中的數據是關聯的(可實踐)
銷燬父組件時,先將子組件銷燬後纔會銷燬父組件 後端

兄弟組件的初始化(mounted以前)分開進行,掛載是從上到下依次進行
當沒有數據關聯時,兄弟組件之間的更新和銷燬是互不關聯的數組

mixin中的生命週期與引入該組件的生命週期是僅僅關聯的,且mixin的生命週期優先執行瀏覽器

測試demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <p>{{message}}</p>
    <keep-alive>
        <my-components msg="hello" v-if="show"></my-components>
    </keep-alive>
</div>
</body>
<script>
    var child = {
        template: '<div>from child: {{msg}}</div>',
        props: ['msg'],
        data: function () {
            return {
                childMsg: 'child1'
            };
        },
        deactivated: function () {
            console.log('component deactivated!');
        },
        activated: function () {
            console.log('component activated');
        }
    };
    var app = new Vue({
        el: '#app',
        data: function () {
            return {
                message: 'father',
                show: true
            };
        },
        beforeCreate: function () {
            console.group('beforeCreate 建立前狀態===============》');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(state);
        },
        created: function () {
            console.group('created 建立完畢狀態===============》');
            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);
            // this.message = 'change';
        },
        beforeUpdate: function () {
            console.group('beforeUpdate 更新前狀態===============》');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
            // this.message = 'change2';
        },
        updated: function () {
            console.group('updated 更新完成狀態===============》');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        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: {
            'my-components': child
        }
    });
</script>
</html>

首先來梳理一下結構:
1.咱們建立了一個Vue根實例命名爲app,將其掛載到頁面id爲app的dom元素上。
2.局部註冊的一個組件child並在根實例中將其註冊使其能夠在根實例的做用域中使用。
3.將子組件用<keep-alive> 包裹,爲接下來的測試做準備。緩存

在谷歌瀏覽器打開開發者工具,開始測試!app

結果:注意區分下 beforeCreate() created() beforeMount() mounted()dom

clipboard.png

頁面渲染優先級
render函數選項 > template選項 > outer HTML.函數

相關文章
相關標籤/搜索