Vue父子組件生命周期
Vue
實例需要經過創建、初始化數據、編譯模板、掛載DOM
、渲染、更新、渲染、卸載等一系列過程,這個過程就是Vue
的生命周期,Vue
中提供的鈎子函數有beforeCreate
、created
、beforeMount
、mounted
、beforeUpdate
、updated
、beforeDestroy
、destroyed
,父子組件嵌套時,父組件和子組件各擁有各自獨立的鈎子函數。
描述
創建過程
創建過程主要涉及beforeCreate
、created
、beforeMount
、mounted
四個鈎子函數。
Parent beforeCreate -> Parent Created -> Parent BeforeMount -> Child BeforeCreate -> Child Created -> Child BeforeMount -> Child Mounted -> Parent Mounted
更新過程
更新過程主要涉及beforeUpdate
、updated
兩個鈎子函數,當父子組件有數據傳遞時才會有生命周期的比較。
Parent BeforeUpdate -> Child BeforeUpdate -> Child Updated -> Parent Updated
銷毀過程
銷毀過程主要涉及beforeDestroy
、destroyed
兩個鈎子函數,本例直接調用vm.$destroy()
銷毀整個實例以達到銷毀父子組件的目的。
Parent BeforeDestroy -> Child BeforeDestroy -> Child Destroyed -> Parent Destroyed
示例
<!DOCTYPE html>
<html>
<head>
<title>Vue父子組件生命周期</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
<script type="text/javascript">
Vue.component("counter", {
props: {
count: {
type: Number,
default: 0
},
},
beforeCreate: function() {
console.log("Child", "BeforeCreate");
},
created: function() {
console.log("Child", "Created");
},
beforeMount: function() {
console.log("Child", "BeforeMount");
},
mounted: function() {
console.log("Child", "Mounted");
},
beforeUpdate: function() {
console.log("Child", "BeforeUpdate");
},
updated: function() {
console.log("Child", "Updated");
},
beforeDestroy: function() {
console.log("Child", "BeforeDestroy");
},
destroyed: function() {
console.log("Child", "Destroyed");
},
template: `
<div>
<div>{{count}}</div>
</div>
`
})
var vm = new Vue({
el: '#app',
data: function(){
return {
count: 1
}
},
beforeCreate: function() {
console.log("Parent", "BeforeCreate");
},
created: function() {
console.log("Parent", "Created");
},
beforeMount: function() {
console.log("Parent", "BeforeMount");
},
mounted: function() {
console.log("Parent", "Mounted");
},
beforeUpdate: function() {
console.log("Parent", "BeforeUpdate");
},
updated: function() {
console.log("Parent", "Updated");
},
beforeDestroy: function() {
console.log("Parent", "BeforeDestroy");
},
destroyed: function() {
console.log("Parent", "Destroyed");
},
template: `
<div>
<counter :count="count"></counter>
<button @click="count++">++</button>
</div>
`
})
</script>
</html>
生命周期
Vue
生命周期鈎子函數功能示例,其中this.msg
初始化賦值Vue Lifecycle
,在更新過程中賦值為Vue Update
。
beforeCreate
從Vue
實例開始創建到beforeCreate
鈎子執行的過程中主要進行了一些初始化操作,例如組件的事件與生命周期鈎子的初始化。在此生命周期鈎子執行時組件並未掛載,data
、methods
等也並未綁定,此時主要可以用來加載一些與Vue
數據無關的操作,例如展示一個loading
等。
console.log("beforeCreate");
console.log(this.$el); //undefined
console.log(this.$data); //undefined
console.log(this.msg); // undefined
console.log("--------------------");
created
從beforeCreate
到created
的過程中主要完成了數據綁定的配置、計算屬性與方法的掛載、watch/event
事件回調等。在此生命周期鈎子執行時組件未掛載到到DOM
,屬性$el
目前仍然為undefined
,但此時已經可以開始操作data
與methods
等,只是頁面還未渲染,在此階段通常用來發起一個XHR
請求。
console.log("created");
console.log(this.$el); //undefined
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Lifecycle
console.log("--------------------");
beforeMount
從created
到beforeMount
的過程中主要完成了頁面模板的解析,在內存中將頁面的數據與指令等進行解析,當頁面解析完成,頁面模板就存在於內存中。在此生命周期鈎子執行時$el
被創建,但是頁面只是在內存中,並未作為DOM
渲染。
console.log("beforeMount");
console.log(this.$el); //<div id="app">...</div>
console.log(this.$data); // {__ob__: Observer}
console.log(this.msg); // Vue Lifecycle
console.log("--------------------");
mounted
從beforeMount
到mounted
的過程中執行的是將頁面從內存中渲染到DOM
的操作。在此生命周期鈎子執行時頁面已經渲染完成,組件正式完成創建階段的最后一個鈎子,即將進入運行中階段。此外關於渲染的頁面模板的優先級,是render
函數 >
template
屬性 >
外部HTML
。
console.log("mounted");
console.log(this.$el); //<div id="app">...</div>
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Lifecycle
console.log("--------------------");
beforeUpdate
當數據發生更新時beforeUpdate
鈎子便會被調用,此時Vue
實例中數據已經是最新的,但是在頁面中的數據還是舊的,在此時可以進一步地更改狀態,這不會觸發附加的重渲染過程。在上述例子中加入了debugger
斷點,可以觀察到Vue
實例中數據已經是最新的,但是在頁面中的數據還是舊的。
// this.msg = "Vue Update";
console.log("beforeUpdate");
console.log(this.$el); //<div id="app">...</div>
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Update
console.log("--------------------");
updated
當數據發生更新並在DOM
渲染完成后updated
鈎子便會被調用,在此時組件的DOM
已經更新,可以執行依賴於DOM
的操作。
// this.msg = "Vue Update";
console.log("updated");
console.log(this.$el); //<div id="app">...</div>
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Update
console.log("--------------------");
beforeDestroy
在Vue
實例被銷毀之前beforeDestroy
鈎子便會被調用,在此時實例仍然完全可用。
// this.$destroy();
console.log("beforeDestroy");
console.log(this.$el); //<div id="app">...</div>
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Update
console.log("--------------------");
destroyed
在Vue
實例被銷毀之后destroyed
鈎子便會被調用,在此時Vue
實例綁定的所有東西都會解除綁定,所有的事件監聽器會被移除,所有的子實例也會被銷毀,組件無法使用,data
和methods
也都不可使用,即使更改了實例的屬性,頁面的DOM
也不會重新渲染。
// this.$destroy();
console.log("destroyed");
console.log(this.$el); //<div id="app">...</div>
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Update
console.log("--------------------");
每日一題
https://github.com/WindrunnerMax/EveryDay
參考
https://segmentfault.com/a/1190000011381906
https://www.cnblogs.com/yuliangbin/p/9348156.html
https://www.cnblogs.com/zmyxixihaha/p/10714217.html