---
# System prepended metadata

title: 開發筆記 Vue.js

---

# 開發筆記 Vue.js

:::info
在做學校的客服系統網站系統
朋友用vue.js做為前端框架
本來我都是做後端，但現在為了開發快一點也得開始做前端
所以開始學這個框架
原本只會javascript、typescript而已 angular、React都不會
:::

:::warning
因為有簽保密協議的關係
不會放置專案程式碼在這
頂多就是紀錄一些概念的code而已
:::


## 甚麼是Vue.js

Vue.js是一個javascript**漸進式**框架
焦點是在**狀態與畫面的同步層級**

首先談到vue.js的核心
* 宣告式渲染
* 元件系統


## 指令式渲染、宣告式渲染

* **指令式渲染**
    學習過基本js的人都知道，想要對Html當中某些元素做操作的時候，會使用`querySelector`或`getElementbyId`等functions來操作DOM元素
    https://www.w3schools.com/js/js_htmldom_elements.asp
    還有EventListener等
    
    不難發現，都是一個指令對上一個動作，這樣以**操作DOM為基礎**的模式，稱為指令式渲染
    若有多個元素要連動更新，就會寫出很可怕一長串的程式碼(我就在學校的專案寫過..)

* **宣告式渲染**
    看Vue.js的程式碼就知道
    採用OOP的概念，把DOM的元素內容當成物件來看待
    需要連動更新的時候，不需要把所有DOM通通找出


:::info
Javascript是一個event driven的程式語言
與網頁元素的互動也是圍繞在事件，原本的js可以很直覺的對DOM做操作
但缺點是一旦開發規模增大，容易寫出義大利麵式的程式碼

從前缺少**狀態集中管理**的概念，後端拿到資料丟給前端html，我們就直接用js操作然後顯示，問題是如果某個DOM被刪除了，那是否代表這個資料將永遠拿不到?

之前解決的方法通常是將資料設成global variable，優點就是一開始寫的方便 彈性大，缺點也是相應而生，尤其是要擴充的時候常常就被全域變數卡死(我也在學校專案遇過這種事...上個開發者把東西全部設成全域變數 搞得我想死)
:::
    
    
## MVVM 

MVVM由三個部分組成
* Model 狀態
* View 畫面
* ViewModel

前兩個部分和MVC架構相同
ViewModel則很特別，會**自動將Model和View的狀態同步**
將DOM Listeners和資料綁定一起封裝起來
如果View觸發網頁上的事件，ViewModel裡的Vue.js會將狀態存到Model(js物件)。如果Model狀態被改變，Vue.js也會同步更新View的內容

:::info
延伸閱讀
**DOM Listener**
**DOM data binding**
:::

## 元件系統

這是我認為很厲害的概念
傳統學到的網頁DOM結構就是Tree
每個元素代表一個Node
而Vue.js則認為最小單位不一定只能是Node，可以是組合好的元件單元

每個Component的最小單位可以只是Node，也可以是好幾個Nodes組合而成的元件，元件內還可以有元件。
每個元件都有自己的模板、程式及樣式，整個網頁由元件組合起來，稱為**Component tree**

## 漸進式框架

Vue.js本來只想做為一個小型框架，解決上述兩個核心問題而已
但之後因為開源的特性，規模越來越大，包含了client-side routing、client-server data persistence等等

漸進式框架代表允許開發者以**漸進**的方式來挑選所需要的特性，當專案規模只需要vue.js核心的時候，就只需要載入vue.js核心就可以了

:::info
延伸閱讀
client-side routing
large scale state management
client-server data persistence
:::


## 實作part 1

將以下html顯示
```javascript=
<!DOCTYPE html>
<html>
    <head>
        <script src="https://unpkg.com/vue@next"></script>
    </head>

    <body>
        <div id="prac">
            {{message}}, hi
        </div>
    </body>
</html>

<script>
    const {createApp, ref} = Vue;
    const prac = createApp({
        data() {
            return{
                message: 'your name'
            }
        }
    });

    prac.mount('#prac');
</script>
```

## Methods

在Vue.js當中 定義function的方法是在物件中使用methods
如同以下程式碼
值得注意的是，method當中如果使用箭頭函式，則使用的this會指向更上一層
盡量避免在method用箭頭函式

同樣是function，Vue.js提供了兩種方式實作
* computed
* methods

兩者的差異是甚麼?使用時機又是甚麼?

computed會將計算後的結果暫存 而methods不會
所以相同的計算如果出現數次 computed的function實際上只會計算一次 而methods的functions則會計算多次
所以針對重複計算，computed的效能會比methods來的好
但computed當中的function不能用參數












## Directive


* 與模板相關
    * v-bind
        改變標籤屬性，例如id、class等等

    * v-model
        針對表單類型元素，可以雙向更新
        input、textarea等
        radio則很特別，data內的狀態必須是array

        它還提供修飾子給我們使用，改變更新頻率、做計算等等

    * v-text
    * v-html
    * v-once
    * v-pre

* 與事件相關
    * v-on
        `v-on:[event-name] = '運算式'`
        `@[event-name] = '運算式'`

