###### tags: `Vue2`
# VUE 從頭學 - vue 的生命週期
在學 vue 之前,有幾個我們必須要先知道的,那就是 "資料驅動畫面" 的概念跟 "生命週期"。
關於 "生命週期" 其實不管是不是 vue 還是其他的前端框架,應該都可以算是框架的整個核心,下面會介紹到
## 資料驅動畫面
甚麼是資料驅動畫面呢?
這是有別於一般的網頁開發,在一般我們開發網頁時,如果想要變動某個地方的內容,我們都是透過 JS 去選取它的 class 或是 id 來做更改 :
```
document.querySelector("").xxxx = "";
```
不過資料驅動畫面就不一樣了,它就像是我們宣告了一個變數,只要改變變數的值,畫面就會自動做更新了~ 是不是更 smart 了呢 !! 😁😁
## 生命週期介紹
以下先列上 [vue 官方提供的生命週期圖](https://vuejs.bootcss.com/guide/instance.html#%E5%AE%9E%E4%BE%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90)

瞭解了資料驅動畫面的概念後,接著下面會一一介紹生命週期的每個階段。
* beforeCreate :
在 vue 的元素被建立之前,像是 vue 裡面的 data ... 之類的(像是 data、methods ...都還無法使用)。
* created
vue 的元素都被建立完畢,這時 Vue實體中的配置除了 $el 外已全部配置(data、methods ...已初始化,可以取得其資料),$el 要在掛載模板後才會配置。
* beforeMount
vue 的元素已經建立完畢,還未掛載到網頁的元素上。
* mounted
vue 的元素已經與網頁的元素掛載綁定完畢,達到資料雙向的效果,以例子來說可能比較好理解。
vue 裡面的東西都是 vue 幫我們建立的虛擬 DOM ,而上面說的網頁元素是指 html 的 div 標籤的實體 DOM,所以我們在標籤上加上的 v-model 或是 v-bind ... 等,就是這一步驟就會完成了,在開發上會很常使用到。
* beforeUpdate
當我們要變更 data 裡面變數的值之前。
* updated
我們變動的值已經變更上去並更新畫面了。
* beforeDestroy
在斷開 vue 與實體元素之前。
* destroyed
vue 元素與實體元素之間的連結已經斷開,就算再變更值,也不會更新畫面了。
:::warning
!!! 如果需要使用 click 事件觸發 destroyed 生命週期,需用以下方式
```htmlembedded=
<button v-on:click="$destroy()">Destroy instance</button>
```
:::
:::success
相關說明可以參考(裡面也有附上作者的範例,可以點擊進去看看) - [Vue.js Core 30天屠龍記(第4天): Vue 實體的生命週期](https://ithelp.ithome.com.tw/articles/10202949)
:::
## 跟著實例一起看生命週期
如果你跟我一樣~ 是需要搭配著例子比較好懂類型的人 XD
下面會跟著簡單的例子來看
### 在網頁啟動完畢時,已瞬間來到 mounted

看到了嗎? 只要網頁一打開,就已經經過了生命週期的四個階段,代表 vue 的元素已經被建立好,並且綁訂到指定的實體 DOM 上面了,也就代表我們只要更改 data 裡變數的值,畫面就會跟著被更新
### 更新內容的那瞬間
接著我們可以透過實例畫面上的輸入框來更新 hello 的字樣,這裡示範的做法是用 v-model 綁定輸入內容,再將輸入的內容指定給 hello 字樣的插值變數,更新完畢後也已經跑完 beforeUpdate 跟 updated 兩個生命週期了。

圖中之所以會有那麼多次 beforeUpdate 跟 updated 是因為我在輸入框使用了 v-model ,因此每當輸入一個字,v-model 所綁定的變數都需要更新,進而觸發 beforeUpdate 跟 updated。
### 燒毀 ~ 斷開 vue 的連結,斷開鎖鏈
最後我們來看 beforeDestroy 跟 destroyed 這兩個週期,因為個人在開發上幾乎沒有使用到這個部份,所以怕說錯,特別找了例子來搞懂 🤣🤣
首先,我們先寫了一個按鈕來呼叫 destroyed,所以畫面中的 Destroy instance 按鈕一點擊下去,我們再怎麼點擊 updata 按鈕,畫面也不會更新了。

從圖中右邊的 console 來看,destroyed 被觸發後 vue 就與實體 DOM 的連結被切斷了,雖然綁定 vue ABC 的變數值已經被改成 Orz,但是畫面已經不會更新了。
另一點可以觀察的是,destroyed 後我們變更輸入框的內容,一樣也不再觸發 beforeUpdate 跟 updated。
### 最後附上這篇的範例
```htmlembedded=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
{{msg}}
<button v-on:click="$destroy()">Destroy instance</button>
<input type="text" v-model="text">
<button @click="updatevue">update</button>
<button @click="myconsole">console</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
msg: "hello",
text:""
},
beforeCreate() {
console.log("beforeCreate");
},
created() {
console.log("created");
},
beforeMount() {
console.log("beforeMount");
},
mounted() {
console.log("mounted");
},
beforeUpdate() {
console.log("beforeUpdate");
},
updated() {
console.log("updated");
},
beforeDestroy() {
console.log("beforeDestroy");
},
destroyed() {
console.log('Hook: destroyed');
},
methods:{
myconsole(){
console.log(this.msg);
},
updatevue(){
this.msg = this.text;
}
}
})
</script>
</body>
</html>
```