Vue 生命週期(鉤子函數)

生命週期

實例生命週期鉤子

每一個 Vue 實例在被建立時都要通過一系列的初始化過程——例如,須要設置數據監聽、編譯模板、將實例掛載到 DOM 並在數據變化時更新 DOM 等。同時在這個過程當中也會運行一些叫作生命週期鉤子的函數,這給了用戶在不一樣階段添加本身的代碼的機會。javascript

好比 created 鉤子能夠用來在一個實例被建立以後執行代碼:html

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 實例
    console.log('a is: ' + this.a)
  }
})
// => "a is: 1"

也有一些其它的鉤子,在實例生命週期的不一樣階段被調用,如 mountedupdateddestroyed。生命週期鉤子的 this 上下文指向調用它的 Vue 實例。vue

不要在選項屬性或回調上使用箭頭函數,好比 created: () => console.log(this.a)vm.$watch('a', newValue => this.myMethod())。由於箭頭函數並無 thisthis 會做爲變量一直向上級詞法做用域查找,直至找到爲止,常常致使 Uncaught TypeError: Cannot read property of undefinedUncaught TypeError: this.myMethod is not a function 之類的錯誤。java

生命週期圖示

下圖展現了實例的生命週期。你不須要立馬弄明白全部的東西,不過隨着你的不斷學習和使用,它的參考價值會愈來愈高。ajax

Vue 實例生命週期

<div id="app">
    {{ msg }}
</div>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'hi vue'
        },
        // 在實例初始化以後,數據觀測(data observer)和 event/watcher事件配置以前調用;
        beforeCreate: function () {
            console.log('beforeCreate')
        },
        /* 在實例建立完成後當即調用
        在這一步,實例已完成如下的配置:數據觀測(data observer),屬性和方法的用算,watch/event事件的回調。
        然而掛載的階段還沒開始,$el 屬性目前不可見
        */
        created: function () {
            console.log('created')
        },
        // 在掛載開始以前調用:相關渲染的函數首次被調用
        beforeMount: function () {
            console.log('beforeMount')
        },
        // el 被建立的vm.$el替換,掛載成功
        mounted: function () {
            console.log('mounted')
        },
        // 數據更新時調用
        beforeUpdate: function () {
            console.log('beforeUpdate')
        },
        // 組件dom已經更新, 組件更新完畢
        updated: function () {
            console.log('updated')
        }
    });

    // 設置過時時間
    setTimeout(function () {
        vm.$data.msg = "change ....."
    }, 3000);
</script>

生命週期更多參數查看:https://cn.vuejs.org/v2/api/#beforeCreateapi

生命週期方法

beforeCreate

  • 類型Function緩存

  • 詳細服務器

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

  • 參考生命週期圖示dom

created

  • 類型Function

  • 詳細

    在實例建立完成後被當即調用。在這一步,實例已完成如下的配置:數據觀測 (data observer),屬性和方法的運算,watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。

    發送ajax 實現數據驅動視圖

  • 參考生命週期圖示

beforeMount

  • 類型Function

  • 詳細

    在掛載開始以前被調用:相關的 render 函數首次被調用。

    該鉤子在服務器端渲染期間不被調用。

  • 參考生命週期圖示

mounted

  • 類型Function

  • 詳細

    el 被新建立的 vm.$el 替換,並掛載到實例上去以後調用該鉤子。若是 root 實例掛載了一個文檔內元素,當 mounted 被調用時 vm.$el 也在文檔內。

    • 虛擬dom Recat

    • 獲取真實DOM

    注意 mounted 不會承諾全部的子組件也都一塊兒被掛載。若是你但願等到整個視圖都渲染完畢,能夠用 vm.$nextTick 替換掉 mounted

    mounted: function () {
      this.$nextTick(function () {
        // Code that will run only after the
        // entire view has been rendered
      })
    }

    該鉤子在服務器端渲染期間不被調用。

  • 參考生命週期圖示

beforeUpdate

  • 類型Function

  • 詳細

    數據更新時調用,發生在虛擬 DOM 打補丁以前。這裏適合在更新以前訪問現有的 DOM,好比手動移除已添加的事件監聽器。

    該鉤子在服務器端渲染期間不被調用,由於只有初次渲染會在服務端進行。

  • 參考生命週期圖示

updated

  • 類型Function

  • 詳細

    因爲數據更改致使的虛擬 DOM 從新渲染和打補丁,在這以後會調用該鉤子。

    當這個鉤子被調用時,組件 DOM 已經更新,因此你如今能夠執行依賴於 DOM 的操做。然而在大多數狀況下,你應該避免在此期間更改狀態。若是要相應狀態改變,一般最好使用計算屬性watcher 取而代之。

    注意 updated 不會承諾全部的子組件也都一塊兒被重繪。若是你但願等到整個視圖都重繪完畢,能夠用 vm.$nextTick 替換掉 updated

    updated: function () {
      this.$nextTick(function () {
        // Code that will run only after the
        // entire view has been re-rendered
      })
    }

    該鉤子在服務器端渲染期間不被調用。

  • 參考生命週期圖示

activated

deactivated

beforeDestroy

  • 類型Function

  • 詳細

    實例銷燬以前調用。在這一步,實例仍然徹底可用。

    該鉤子在服務器端渲染期間不被調用。

  • 參考生命週期圖示

destroyed

  • 類型Function

  • 詳細

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

    關閉定時器

    該鉤子在服務器端渲染期間不被調用。

  • 參考生命週期圖示

errorCaptured

2.5.0+ 新增

  • 類型(err: Error, vm: Component, info: string) => ?boolean

  • 詳細

    當捕獲一個來自子孫組件的錯誤時被調用。此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子能夠返回 false 以阻止該錯誤繼續向上傳播。

    你能夠在此鉤子中修改組件的狀態。所以在模板或渲染函數中設置其它內容的短路條件很是重要,它能夠防止當一個錯誤被捕獲時該組件進入一個無限的渲染循環。

    錯誤傳播規則

    • 默認狀況下,若是全局的 config.errorHandler 被定義,全部的錯誤仍會發送它,所以這些錯誤仍然會向單一的分析服務的地方進行彙報。
    • 若是一個組件的繼承或父級從屬鏈路中存在多個 errorCaptured 鉤子,則它們將會被相同的錯誤逐個喚起。
    • 若是此 errorCaptured 鉤子自身拋出了一個錯誤,則這個新錯誤和本來被捕獲的錯誤都會發送給全局的 config.errorHandler
    • 一個 errorCaptured 鉤子可以返回 false 以阻止錯誤繼續向上傳播。本質上是說「這個錯誤已經被搞定了且應該被忽略」。它會阻止其它任何會被這個錯誤喚起的 errorCaptured 鉤子和全局的 config.errorHandler

使用生命週期(鉤子函數)

beforeCreate(){

    // 組件建立以前

    console.log(this.msg);

},

created(){

    // 組件建立以後

    // 使用該組件,就會觸發以上的鉤子函數,created中能夠操做數據,發送ajax,而且能夠實現vue==》頁面的影響  應用:發送ajax請求

    console.log(this.msg);

    // this.msg = '嘿嘿黑';

},

beforeMount(){

    // 裝載數據到DOM以前會調用

    console.log(document.getElementById('app'));

},

mounted(){

    // 這個地方能夠操做DOM

    // 裝載數據到DOM以後會調用 能夠獲取到真實存在的DOM元素,vue操做之後的DOM

    console.log(document.getElementById('app'));

},

beforeUpdate(){

    // 在更新以前,調用此鉤子,應用:獲取原始的DOM

    console.log(document.getElementById('app').innerHTML);

},

updated(){

    // 在更新以前,調用此鉤子,應用:獲取最新的DOM

    console.log(document.getElementById('app').innerHTML);

},

beforeDestroy(){

    console.log('beforeDestroy');

},

destroyed(){

    console.log('destroyed');

},

activated(){

    console.log('組件被激活了');

},

deactivated(){

    console.log('組件被停用了');

}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>

<script src="../vue.js"></script>
<script>

    let Test = {
        data: function () {
            return {
                msg: 'alex',
                count: 0,
                timer: null
            }
        },
        template: `
            <div>
                <p>{{ count }}</p>
                <div id="box">{{ msg }}</div>
                <button v-on:click="changeHandler">修改</button>
            </div>
        `,
        methods: {
            changeHandler: function () {
                this.msg = 'wusir';
                document.querySelector('#box').style.backgroundColor('red')
            }
        },
        beforeCreate() {
            // 組件建立以前
            console.log('組件建立以前', this.msg);
        },

        created() {
            // 重要****
            // 組件建立以後
            // 使用該組件,就會觸發以上的鉤子函數,created中能夠操做數據,發送ajax,而且能夠實現vue==》頁面的影響  應用:發送ajax請求
            console.log('組件建立以後', this.msg);
            this.timer = setInterval(() => {
                this.count++
            }, 1000);
            // this.msg = '嘿嘿黑';
        },
        beforeMount() {
            // 裝載數據到DOM以前會調用
            console.log(document.getElementById('app'));
        },

        mounted() {
            // 這個地方能夠操做DOM
            // 裝載數據到DOM以後會調用 能夠獲取到真實存在的DOM元素,vue操做之後的DOM
            console.log(document.getElementById('app'));
        },

        beforeUpdate() {
            // 在更新以前,調用此鉤子,應用:獲取原始的DOM
            console.log(document.getElementById('app').innerHTML);
        },

        updated() {
            // 在更新以前,調用此鉤子,應用:獲取最新的DOM
            console.log(document.getElementById('app').innerHTML);
        },
        beforeDestroy() {
            console.log('beforeDestroy');
        },

        destroyed() {
            // 定時器的消耗在此方法處理 關閉清楚
            console.log('destroyed',this.timer);
            clearInterval(this.timer);
        },

        activated() {
            console.log('組件被激活了');
        },

        deactivated() {
            console.log('組件被停用了');
        }
    };

    let App = {
        data: function () {
            return {
                isShow: true
            }
        },
        template: `
            <div>
                 <keep-alive>
                    <Test v-if="isShow"/>
                </keep-alive>
                <button @click="clickRemove">改變test組件的生死</button>
            </div>
        `,
        methods: {
            clickRemove: function () {
                this.isShow = !this.isShow
            }
        },
        components: {
            Test
        }
    };

    let vm = new Vue({
        el: '#app',
        data: function () {
            return {}
        },
        components: {
            App
        }
    })
</script>
</body>
</html>
相關文章
相關標籤/搜索