淺談vue —— 生命週期

記於vue生命週期的學習

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


好比咱們常常用到的created鉤子:

export default { 
    created() { 
        ...在這裏咱們一般發起異步請求,獲得數據 
        
    } 
    
} 


<!--注意-->
<!--
    這裏的created函數不能使用箭頭函數,由於箭頭函數中的this指向的是上一級的this。
-->
複製代碼

接下來咱們看一下有哪些鉤子函數:

生命週期圖

方法 做用
beforeCreate 組件實例剛被建立,在data屬性以前。
created 組件實例建立完成,data屬性、computed、props、methods、watch已綁定,但DOM還未生成。
beforeMount
mounted DOM已生成,但不保證已所有掛載在document中(用this.$nextTick 能夠保證已經在document中)
beforeUpdate
updated 更新時觸發
beforeDestroy 組件銷燬以前觸發 (能夠用於清除定時器,取消全局的註冊事件),此時的this仍是指向vue實例
destroyed 此時的this不指向vue實例

單個組件的生命週期

<template lang="html">
    <div class="life-cycle">
        <h1 ref="title">lifr-cycle</h1>

        <h2>{{ a }} {{watchVal}}</h2>

        <ul>
            <li v-for="(item, index) in data" ref="item" @click="setNumber(index)">{{ item }}</li>
        </ul>

        <button type="button" name="button" @click="setData">設置item的個數</button>
        
        <!--<child-file-cycle :data="data"></child-file-cycle>-->
    </div>
</template>

<script>

let oDDEven = true;

import {mapGetters} from "vuex"
import childFileCycle from "./childFileCycle"
export default {
    data() {
        return {
            number: 1,
            watchVal: 1,
            data: ["Hellow"]
        }
    },
    computed: {
        ...mapGetters([
            "value"
        ]),
    },
    // 組件實例剛被建立,在data屬性以前。
    beforeCreate() {
        this.a = "a"
        console.log(this.$el, "---", this.data, "---", "beforeCreate", "---", this.$refs.title, "---", this.value);
    },
    // 組件實例建立完成,data屬性、computed、props、methods、watch已綁定,但DOM還未生成。
    created() {
        setTimeout(() => {
            this.data = ["Javascript", "Java", "PHP"];
        }, 3000);

        console.log(this.watchVal);
        console.log(this.$el, "---", this.data, "---", "created", "---", this.$refs.title, "---", this.value);
    },
    beforeMount() {
        console.log(this.$el, "---", this.data, "---", "beforeMount", "---", this.$refs.title, "---", this.value);
    },
    // DOM已生成,但不保證已所有掛載在document中(用this.$nextTick 能夠保證已經在document中)
    mounted() {
        this.$nextTick(() => {
            console.log(this.$el, "---", this.data, "---", "mounted", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
        })
        console.log(this.$el, "---", this.data, "---", "mounted", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
    },
    beforeUpdate() {
        console.log(this.$el, "---", this.data, "---", "beforeUpdate", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
    },
    // 更新時觸發
    updated() {
        console.log(this.$el, "---", this.data, "---", "update", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
    },
    beforeDestroy() {
        console.log(this.$el, "---", this.data, "---", "beforeDestory", "---", this.$refs.title);
    },
    destroyed() {
        console.log(this.$el, "---", this.data, "---", "destroyed", "---", this.$refs.title);
    },
    methods: {
        setNumber(index) {
            this.number = index;
            console.log(index);
        },
        setData() {
            if (oDDEven) {
                this.data = ["hellow"];
                oDDEven = false;

                return;
            }

            this.data = ["Javascript", "Java", "PHP"];
            oDDEven = true;
        }
    },
    watch: {
        watchVal: function(newVal, oldVal) {
            return newVal;
        }
    },
    components: {
        childFileCycle
    }
}
</script>

<style lang="css">
</style>

複製代碼

結果

由上述執行結果:

咱們能夠得出,每個vue實例都會執行beforeCreat、created、beforeMount、mounted這四個鉤子而且只執行一次,
再有數據(必須是與視圖綁定的數據)更新的時候纔會執行beforeUpdate、updated這兩個鉤子,
beforeDestroy、destroyed在視圖銷燬的時候觸發。
複製代碼

子組件

<template lang="html">
    <div class="child-file-cycle">
        <h2>child-file-cycle</h2>
        <div class="">
            child - {{ number }}
        </div>
        <button type="button" name="button" @click="setNumber">setNumber</button>
        <ul>
            <li v-for="(item, index) in data" ref="item" @click="setNumber(index)">child - {{ item }}</li>
        </ul>
    </div>
</template>

<script>
export default {
    props: {
        data: {
            type: Array,
            default: []
        }
    },
    data() {
        return {
            number: Math.random()
        }
    },
    computed: {
    },
    // 組件實例剛被建立,在data屬性以前。
    beforeCreate() {
        console.log("beforeCreate");
    },
    // 組件實例建立完成,data屬性、computed、props、methods、watch已綁定,但DOM還未生成。
    created() {
        console.log("created", this.data);
    },
    beforeMount() {
        console.log("beforeMount");
    },
    // DOM已生成,但不保證已在document中(用this.$nextTick 能夠保證已經在document中)
    mounted() {
        console.log("mounted");
    },
    beforeUpdate() {
        console.log("beforeUpdate");
    },
    // 更新時觸發
    updated() {
        console.log("update");
    },
    beforeDestroy() {
        console.log("beforeDestory");
    },
    destroyed() {
        console.log("destroyed");
    },
    methods: {
        setNumber() {
            this.number = Math.random();
        }
    }
}
</script>

<style lang="css">
</style>

複製代碼

結果圖

在父組件的beforeMount鉤子以後會執行子組件一系列的鉤子函數,將子組件掛載在父組件以後,再將父組件掛載。css


更新props影響的鉤子函數

結果圖

更新props的值的時候,會觸發父組件的beforeUpdate,同時也會觸發子組件的beforeUpadte、updated鉤子,最後觸發父組件的updated鉤子。html


再一次感謝您花費時間閱讀這份稿!vue

做者 [@xinwuliu][2]
2018 年 05月 08日vuex

相關文章
相關標籤/搜索