Vue父子元件生命週期
阿新 • • 發佈:2020-09-19
# 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
```
### 示例
```html
Vue父子元件生命週期
```
## 生命週期
`Vue`生命週期鉤子函式功能示例,其中`this.msg`初始化賦值`Vue Lifecycle`,在更新過程中賦值為`Vue Update`。
### beforeCreate
從`Vue`例項開始建立到`beforeCreate`鉤子執行的過程中主要進行了一些初始化操作,例如元件的事件與生命週期鉤子的初始化。在此生命週期鉤子執行時元件並未掛載,`data`、`methods`等也並未繫結,此時主要可以用來載入一些與`Vue`資料無關的操作,例如展示一個`loading`等。
```javascript
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`請求。
```javascript
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`渲染。
```javascript
console.log("beforeMount");
console.log(this.$el); //...
console.log(this.$data); // {__ob__: Observer}
console.log(this.msg); // Vue Lifecycle
console.log("--------------------");
```
### mounted
從`beforeMount`到`mounted`的過程中執行的是將頁面從記憶體中渲染到`DOM`的操作。在此生命週期鉤子執行時頁面已經渲染完成,元件正式完成建立階段的最後一個鉤子,即將進入執行中階段。此外關於渲染的頁面模板的優先順序,是`render`函式 `> ` `template`屬性 `>` 外部`HTML`。
```javascript
console.log("mounted");
console.log(this.$el); //...
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Lifecycle
console.log("--------------------");
```
### beforeUpdate
當資料發生更新時`beforeUpdate`鉤子便會被呼叫,此時`Vue`例項中資料已經是最新的,但是在頁面中的資料還是舊的,在此時可以進一步地更改狀態,這不會觸發附加的重渲染過程。在上述例子中加入了`debugger`斷點,可以觀察到`Vue`例項中資料已經是最新的,但是在頁面中的資料還是舊的。
```javascript
// this.msg = "Vue Update";
console.log("beforeUpdate");
console.log(this.$el); //...
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Update
console.log("--------------------");
```
### updated
當資料發生更新並在`DOM`渲染完成後`updated`鉤子便會被呼叫,在此時元件的`DOM`已經更新,可以執行依賴於`DOM`的操作。
```javascript
// this.msg = "Vue Update";
console.log("updated");
console.log(this.$el); //...
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Update
console.log("--------------------");
```
### beforeDestroy
在`Vue`例項被銷燬之前`beforeDestroy`鉤子便會被呼叫,在此時例項仍然完全可用。
```javascript
// this.$destroy();
console.log("beforeDestroy");
console.log(this.$el); //...
console.log(this.$data); //{__ob__: Observer}
console.log(this.msg); // Vue Update
console.log("--------------------");
```
### destroyed
在`Vue`例項被銷燬之後`destroyed`鉤子便會被呼叫,在此時`Vue`例項繫結的所有東西都會解除繫結,所有的事件監聽器會被移除,所有的子例項也會被銷燬,元件無法使用,`data`和`methods`也都不可使用,即使更改了例項的屬性,頁面的`DOM`也不會重新渲染。
```javascript
// this.$destroy();
console.log("destroyed");
console.log(this.$el); //...
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
```