當你開始寫比較大的專案,或看技術文章時,常會看到 MVC、MVVM、MVP 這些名詞。到底這些是什麼?Vue 用的是哪一種?什麼時候該用什麼?
這篇用最白話的方式幫你搞懂。
🎯 先懂一個核心觀念:為什麼要分層?
想像你開一間餐廳:
- 外場服務生:跟客人互動、點餐、送餐
- 廚房:處理食材、烹飪
- 倉庫:存放食材
如果你把這三件事都交給同一個人做,會發生什麼事?
- 忙不過來
- 出錯時不知道問題在哪
- 換人很難交接
程式也一樣。分層的目的是:讓每個部分只做一件事,出問題時好找、好改、好維護。
📐 MVC:最經典的分層架構
MVC 是什麼?
M = Model(資料層) → 負責資料、業務邏輯
V = View(視圖層) → 負責顯示畫面
C = Controller(控制層)→ 負責接收指令、協調 M 和 V運作流程
使用者操作 View
↓
Controller 接收指令
↓
Controller 操作 Model(取得/修改資料)
↓
Model 更新後通知 View
↓
View 重新渲染畫面舉個例子
你在購物網站點「加入購物車」:
- View:顯示商品頁面、按鈕
- Controller:監聽按鈕點擊,呼叫 Model
- Model:把商品加入購物車資料,通知 View 更新
- View:購物車圖示顯示 +1
優點
- ✅ 結構清楚,職責分明
- ✅ 經典成熟,很多人懂
- ✅ 適合後端(Rails、Laravel、Django 都用這套)
缺點
- ❌ Controller 容易變肥(什麼都塞進去)
- ❌ View 和 Model 的溝通有時候繞路
- ❌ 在前端框架裡不是很直覺
🔄 MVVM:Vue 的核心架構
MVVM 是什麼?
M = Model(資料層) → 負責資料
V = View(視圖層) → 負責顯示
VM = ViewModel(視圖模型)→ 連接 V 和 M,處理邏輯跟 MVC 最大的差別
MVVM 有一個神奇的機制:雙向綁定(Two-way Binding)
View(畫面)←→ ViewModel ←→ Model(資料)
↑________________↑
自動同步!當資料改變,畫面自動更新;當使用者在畫面上輸入,資料也自動改變。
Vue 裡的 MVVM
<template>
<!-- 這是 View -->
<input v-model="message">
<p>{{ message }}</p>
</template>
<script>
export default {
data() {
return {
// 這是 Model
message: "Hello"
}
},
// 這整個 Vue 元件就是 ViewModel
// 它把 View 和 Model 綁在一起
}
</script>你不用手動寫「當資料改變時更新畫面」,Vue 幫你處理好了。
優點
- ✅ 雙向綁定超方便,少寫很多程式碼
- ✅ View 和 Model 分離乾淨
- ✅ 非常適合前端 SPA 應用
- ✅ Vue、Angular 都用這套
缺點
- ❌ 雙向綁定在大型專案可能造成難以追蹤的更新
- ❌ ViewModel 也可能變肥
- ❌ Debug 時有時候不知道資料從哪裡被改的
📊 MVP:Controller 的進化版
MVP 是什麼?
M = Model(資料層)
V = View(視圖層)
P = Presenter(主持人)跟 MVC 很像,但 View 和 Model 完全不直接溝通,所有事情都經過 Presenter。
流程
View → Presenter → Model
↓
View ← Presenter ← Model優點
- ✅ View 和 Model 完全解耦
- ✅ 非常好寫測試
- ✅ 邏輯集中在 Presenter
缺點
- ❌ Presenter 容易變超肥
- ❌ 程式碼量比 MVVM 多
- ❌ 前端用得比較少(Android 開發比較常見)
🔀 Flux / Vuex / Pinia:狀態管理架構
當專案變大,元件之間要共享資料時,MVVM 的雙向綁定會變得很亂。這時候需要「狀態管理」。
核心概念
┌─────────────────────────────────────────┐
│ 單向資料流 │
│ │
│ View → Action → Mutation → State │
│ ↑________________________________│ │
│ │
└─────────────────────────────────────────┘- State:唯一的資料來源
- View:根據 State 顯示畫面
- Action:使用者操作觸發動作
- Mutation:唯一能修改 State 的方法
Vuex vs Pinia
| Vuex | Pinia | |
|---|---|---|
| 語法 | 比較囉唆 | 簡潔很多 |
| TypeScript | 支援但麻煩 | 原生支援 |
| Mutation | 必須要有 | 可以直接改 State |
| 推薦度 | Vue 2 時代的主流 | Vue 3 官方推薦 |
優點
- ✅ 資料流清楚可追蹤
- ✅ 適合大型專案
- ✅ Debug 方便(有時光旅行功能)
缺點
- ❌ 小專案用起來很笨重
- ❌ 學習成本較高
- ❌ 程式碼量增加
🧩 Composition API:Vue 3 的新風格
這不是架構模式,而是 Vue 3 提供的新寫法。
Options API(舊寫法)
export default {
data() {
return { count: 0 }
},
methods: {
increment() {
this.count++
}
},
computed: {
doubled() {
return this.count * 2
}
}
}Composition API(新寫法)
import { ref, computed } from "vue"
export default {
setup() {
const count = ref(0)
const increment = () => count.value++
const doubled = computed(() => count.value * 2)
return { count, increment, doubled }
}
}或更簡潔的 <script setup>:
<script setup>
import { ref, computed } from "vue"
const count = ref(0)
const increment = () => count.value++
const doubled = computed(() => count.value * 2)
</script>Composition API 的好處
- ✅ 相關邏輯可以放在一起(不用在 data、methods、computed 之間跳來跳去)
- ✅ 邏輯可以抽成 composable 重用
- ✅ TypeScript 支援更好
- ✅ 程式碼更容易組織
什麼時候用 Composition API?
| 情況 | 建議 |
|---|---|
| 新專案 | 直接用 Composition API |
| 舊專案維護 | 維持 Options API 不要混用 |
| 小元件 | Options API 也很夠用 |
| 複雜邏輯、需要重用 | Composition API 優勢大 |
📋 架構風格比較總表
| 架構 | 核心概念 | 適合場景 | 前端常見度 |
|---|---|---|---|
| MVC | Controller 協調一切 | 後端、傳統網頁 | ⭐⭐ |
| MVVM | 雙向綁定 | Vue、Angular | ⭐⭐⭐⭐⭐ |
| MVP | View/Model 完全分離 | Android、測試導向 | ⭐ |
| Flux/Vuex/Pinia | 單向資料流 | 大型 SPA | ⭐⭐⭐⭐ |
🎯 給 Vue 開發者的建議
小專案(1-5 個頁面)
MVVM(Vue 預設)
+ Options API 或 Composition API
+ 不需要 Pinia中型專案(5-20 個頁面)
MVVM
+ Composition API
+ Pinia(如果有跨元件狀態)
+ 抽 composables 重用邏輯大型專案(20+ 頁面)
MVVM + 單向資料流思維
+ Composition API
+ Pinia(必備)
+ 嚴格的資料夾結構
+ 可能需要分層(services / repositories)💡 跟 AI 協作的提示
當你請 AI 幫你寫程式,可以這樣說:
請用 Vue 3 Composition API + Pinia 幫我寫一個購物車功能,
遵循以下結構:
- 元件放 components/
- 狀態管理放 stores/
- 可重用邏輯抽成 composables/
資料流要清楚:元件 → action → store → 元件更新這樣 AI 就知道你要什麼架構,不會亂寫。
結語
架構沒有絕對的好壞,只有適不適合:
- 小專案:用 Vue 預設的 MVVM 就很夠
- 需要共享狀態:加上 Pinia
- 邏輯複雜:用 Composition API 組織程式碼
- 大型團隊:嚴格的資料夾結構 + 單向資料流
記住這句話:
架構是為了讓程式碼好維護,不是為了炫技。從簡單開始,需要時再加。
不要一開始就上全套 Vuex + TypeScript + 微服務,等專案真的需要時再說。