---
# System prepended metadata

title: VUE 從頭學 - vue 的生命週期
tags: [Vue2]

---

###### 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)

![](https://i.imgur.com/3SyhpJH.png)



瞭解了資料驅動畫面的概念後，接著下面會一一介紹生命週期的每個階段。

* 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

![](https://i.imgur.com/G3cIykJ.png)

看到了嗎? 只要網頁一打開，就已經經過了生命週期的四個階段，代表 vue 的元素已經被建立好，並且綁訂到指定的實體 DOM 上面了，也就代表我們只要更改 data 裡變數的值，畫面就會跟著被更新

### 更新內容的那瞬間

接著我們可以透過實例畫面上的輸入框來更新 hello 的字樣，這裡示範的做法是用 v-model 綁定輸入內容，再將輸入的內容指定給 hello 字樣的插值變數，更新完畢後也已經跑完 beforeUpdate 跟 updated 兩個生命週期了。

![](https://i.imgur.com/jI7kjTr.png)

圖中之所以會有那麼多次 beforeUpdate 跟 updated 是因為我在輸入框使用了 v-model ，因此每當輸入一個字，v-model 所綁定的變數都需要更新，進而觸發 beforeUpdate 跟 updated。

### 燒毀 ~ 斷開 vue 的連結，斷開鎖鏈

最後我們來看 beforeDestroy 跟 destroyed 這兩個週期，因為個人在開發上幾乎沒有使用到這個部份，所以怕說錯，特別找了例子來搞懂 🤣🤣

首先，我們先寫了一個按鈕來呼叫 destroyed，所以畫面中的 Destroy instance 按鈕一點擊下去，我們再怎麼點擊 updata 按鈕，畫面也不會更新了。

![](https://i.imgur.com/1RW7LMr.png)

從圖中右邊的 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>
```