---
# System prepended metadata

title: 2.1 - Vue Instance (實例)
tags: [Vue]

---

# 2.1 - Vue Instance (實例)

:::info
- [Re Vue 重頭說起｜Day 2：實體化與模板語法](https://www.youtube.com/watch?v=52Uu1VhsYI8)
- https://cn.vuejs.org/v2/guide/instance.html
:::

<!-- [TOC] -->

這篇會介紹
- Vue 的響應式資料
- 內建的屬性 & 方法
- 生命週期函數

---

## Vue 實例

:::info
每一個 Vue Application 都一定是從一個 Vue Instance 開始
:::

```jsx
var vm = new Vue({})
```

Vue 並沒有完全遵照 MVVM，但他的設計的確受到 MVVM 的啟發（data-binding）。

![](https://i.imgur.com/DyOC2sj.png =400x)

---

## 響應式資料

```jsx
var data = { meg: "Hello Vue" }

var vm = new Vue({
  data: data
})
```

| 原本的 data 長這樣 |放進 Vue 之後，被變成響應式資料 |
|:---:|:---:|
|![](https://i.imgur.com/HMmq7j3.png =300x)| ![](https://i.imgur.com/PAKh0vs.png =300x)|

<!-- #### 資料會同步改變 -->

- 若將 `vm.msg` 改成 `456`，外面的 `data.msg` 也會同步改變

![](https://i.imgur.com/viBf7Ny.png =350x)


<!-- #### Vue 實例化後才新增的屬性，不會同步改變 -->
- 若事後新增一個屬性 `vm.b`，b 屬性不會同步改變
```
vm.b = 'hi'
```
<!-- --- -->

<!-- > 使用 Vue 做網站，除了切版外，還需事先想好 data 架構 -->
<!-- |畫面| 資料架構 |
|---|---|
| ![](https://i.imgur.com/Isgz3Kw.png =300x) | ![](https://i.imgur.com/5VNAvFC.png =300x) | -->

---

### `Object.freeze` 凍結資料

加上 Object.freeze，Vue 就不會把你的資料轉成**響應式資料**

```jsx
// Our data object
var data = { meg: "Hello Vue" }

Object.freeze(data)

// The object is added to a Vue instance
var vm = new Vue({
  data: data
})
```
執行結果
![](https://i.imgur.com/mD556pZ.png =250x)

> 貼心提醒：專案裡面不要亂用 Object.freeze，若想改善效能，可以先嘗試把 data 體積變小

---

## Vue 內建屬性和方法

Vue 內建的屬性和方法會有一個 `$` 前綴，用來跟使用者自訂方法 (Methods) 做區別

```jsx
var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})

vm.$data === data // => true
vm.$el === document.getElementById('example') // => true

// $watch is an instance method
vm.$watch('a', function (newValue, oldValue) {
  // This callback will be called when `vm.a` changes
})
```

#### Vue 實例常用的 API

<table>
<tr>
    <th>屬性</th>
    <th>方法</th>   
</tr>
<tr>
<td>

```jsx
vm.$data
vm.$props
vm.$el
vm.$parent
vm.$root
vm.$children
vm.$slots
vm.$refs
vm.$attrs
vm.$listeners
```

</td>
<td>
方法: 数据

```
vm.$watch
```
方法: 事件
```
vm.$on
vm.$emit
```
方法: 生命周期
```
vm.$mount
vm.$forceUpdate
vm.$nextTick
vm.$destroy
```
</td>
</tr>
</table>


[參考：所有 Vue 內建的屬性和方法](https://cn.vuejs.org/v2/api/#%E5%AE%9E%E4%BE%8B-property)

---

## Vue 生命週期

### Hook Function 鉤子函數
:::info

Vue 生命週期分成很多段落，每一個段落都會自動 “勾”上一個函數，在到達時直接呼叫它。

生命週期：Vue 實例化 -> Init -> Mount ( -> Update ) -> Destroy
:::

#### Init
##### `beforeCreate`
時機：Vue 實例(this) 已被創建。此時可設定資料，方便下一階段使用。

##### `created`
created 執行之後，會依序檢查兩件事：
1. 是否有設定 el 選項
2. 是否設定 template 選項
> 
> - 如果有設定 el 選項 -> 檢查是否有 Template
>     - 有 Template 就採用它
>     - 沒有 Template，就渲染外面的 html
> 
> - 如果沒設定 el 選項：**會停下來**，等到 $vm.mounted 被呼叫

---

#### Mount
**`beforeMount`** -> （創建 vm.$el，並把對應的 dom 元素取代掉）-> **`mounted`**

---

#### Update (資料改動時)
**`beforeUpdate`** -> （重新渲染畫面）-> **`updated`**

---

#### Destroy
##### `beforeDestroy`
- 可用來銷毀計時器和事件
> 若用 Vue API 綁定事件，銷毀時會比較方便

---

:::warning
注意：
- Vue 生命週期不支援非同步，不要嘗試中斷生命週期
- 不要在 Hook 使用箭頭函數，會找不到 `this`
:::
```jsx
new Vue({
// Don't
created: () => { ... }
// Do
created: function () {... }
})
```

---

##### 生命週期示意圖

![](https://i.imgur.com/R9wBhg8.png =600x)

###### tags: `Vue`
