記於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鉤子之後會執行子元件一系列的鉤子函式,將子元件掛載在父元件之後,再將父元件掛載。
更新props影響的鉤子函式
更新props的值的時候,會觸發父元件的beforeUpdate,同時也會觸發子元件的beforeUpadte、updated鉤子,最後觸發父元件的updated鉤子。
再一次感謝您花費時間閱讀這份稿!
作者 [@xinwuliu][2]
2018 年 05月 08日