延續 Day 3 的思維,我們從使用者需求出
發,連續五天打造了一個可以動起來的前端飲料點單系統。
在 AI 可以協助撰寫並優化程式碼的今天,更重要的其實是 工程思維:如何用技術實現滿足使用者需求的完整 Application。
至於過程中採用的工具與框架,往往取決於團隊的習慣與規範,而不只是語法本身。
今天我們要加固 chapter 1:
整理這五天的知識點與功能,反思它們的關聯與差異,並思考下一步如何走向後端 API 串接
與 Vue 專案的組件化管理
。
本學習書籍魔法書使用napkin協助製作
五天的練習讓我們完成了一個可以運作的前端專案:
v-if
、:disabled
@click
v-model
:class
reactive
陣列、刪除、統計這些都是進入 Vue 世界的基礎「魔法咒語」。
但我們的應用仍然侷限在 前端,資料全存在 client side。
未來若要進一步:
Day | 主要功能 | 對應 Vue 技術 | User Story 摘要 |
---|---|---|---|
1 | 飲料流程判斷與送出條件 | v-if 、:disabled |
使用者可以逐步選飲料、甜度、冰量,系統判斷是否可送出 |
2 | 事件觸發新增訂單 | @click |
使用者按下「送出」即可新增一筆訂單 |
3 | 輸入姓名與備註 | v-model |
記錄點餐者名稱與備註 |
4 | 狀態驅動樣式 | :class |
根據填寫狀態與條件,顯示不同顏色與樣式 |
5 | 清單管理與統計 | reactive 陣列、computed |
使用者可檢視、刪除與統計訂單 |
✅ 這張表讓我們一目瞭然地看見功能如何與 Vue 技術對應,也能快速想像未來的擴充點。
在實作過程中,我們已經接觸到 v-model / @input :value 與 ref / reactive 這兩組「兄弟功能」。
它們在概念上有一些重疊,但使用場景略有不同。
我們身為魔法師,技藝專精不斷的追求更強
探究魔法的深淵才是最後的答案!!
否則被取代的舊是固化的思維書籍
差異點 | v-model | @input + :value |
---|---|---|
語法 | 雙向綁定的語法糖 | 需要手動監聽與更新 |
使用場景 | 表單輸入、即時資料同步 | 自訂更細節的事件流程 |
範例:
<!-- v-model 寫法 -->
<input v-model="name" />
<!-- 等價於 -->
<input :value="name" @input="name = $event.target.value" />
我們先來拆解一下如果先把資料state bind(v-bind)上input框框的value
<template>
<div>
<!-- 單向綁定 -->
<input type="text" :value="text" />
<p>輸入的值:{{ text }}</p>
</div>
</template>
<script>
export default {
data() {
return {
text: 'Hello Vue'
}
}
}
</script>
這種寫法會造成什麼樣的後果呢!?
答案就是
一開始 input 內有 Hello Vue。
但你在輸入框輸入新文字時,text 不會改變。
所以 仍然顯示 Hello Vue。
那如果反過來我是做@input
或是做@change
的動作呢?
這邊必須提一下因為我們要呈現
如果是資料改變state然後更新再UI以及 的html tag會發生什麼事情
所以這邊多一個按鈕來模擬state因為事件
發生改變的
<template>
<div>
<!-- 沒有 v-model,也沒有 :value -->
<input type="text" @change="handleChange" />
<!-- 顯示資料 -->
<p>text 資料:{{ text }}</p>
<!-- 用按鈕修改 text -->
<button @click="changeText">點我把 text 改成 ABC</button>
</div>
</template>
<script>
export default {
data() {
return {
text: ''
}
},
methods: {
handleChange(event) {
// 只有離開輸入框或 Enter 才會更新
this.text = event.target.value
},
changeText() {
// 用程式強制修改 text
this.text = 'ABC'
}
}
}
</script>
我們觀察到的結果就是
1.初始狀態 : input 是空白。 顯示 text 資料:。
輸入中 : 你在輸入框輸入「hello」,text 不會馬上更新。
直到輸入框失焦或按 Enter,@change 才觸發 → 顯示 hello。
點擊按鈕 : 當你點「點我把 text 改成 ABC text的state 變成 ABC。
input 仍然顯示你之前輸入的值(例如 hello),因為沒有 :value 綁定。
總結:
1.@change:只會在輸入框完成輸入後更新一次資料。
2.沒有 :value:當程式改變資料(例如按鈕點擊改變),輸入框不會同步顯示新的值。
3.這個範例清楚呈現了資料和畫面分離的效果。
我們可能會想到為什麼會需要資料也要更新的input的情境呢?
你可以試想,今天如果有些三層的下拉選單會透過api傳回來更新state
那我們沒有更新的選單會不會造成選單使用上的問題!!?
問題可大了呢!!!
這種情形就是可能會遇到問題的小細節
也是工程師必須注意的地方
特性 | ref | reactive |
---|---|---|
回傳 | { value: ... } |
Proxy 物件 |
取值 (JS) | 需 .value |
直接屬性存取 |
取值 (template) | 自動解包,可直接使用 | 直接使用 |
深層追蹤 | ✅ 如果 .value 是物件,內部也會自動轉為 reactive | ✅ 會追蹤 |
整個值替換 | ✅ refVar.value = newObj 保持響應 |
⚠️ state = newObj 會失去響應,需 Object.assign |
解構 (destructure) | ✅ 保持響應 | ⚠️ 需搭配 toRefs() |
需求 | 建議 |
---|---|
單一基本值(數字、字串、布林) | ref |
DOM 或元件實例 | ref |
需要頻繁整個替換物件 | ref |
多屬性、巢狀狀態 | reactive |
解構後仍要響應 | reactive + toRefs() |
指的是在應用中,某段狀態常常一次性用新物件取代舊物件,
而不是逐一修改其中幾個屬性。
使用情境 | 為什麼需要整個替換 |
---|---|
表單重置 | 使用者點「重填」或切換帳號,需要用全新的資料物件覆蓋目前的表單值。 |
切換列表項目 | 例如點選不同的「商品」、「用戶」、「文章」,要直接以選中的整個資料物件取代目前顯示的內容。 |
取得最新狀態 | 從 API 重新抓取最新狀態(例如設定檔、訂單資料)時,直接以 API 回傳的物件覆蓋本地狀態。 |
狀態回溯或還原 | 點「復原/復舊」按鈕時,用先前快照完整替換。 |
ref
更適合state = newObj // ❌ 不會再是 reactive
Object.assign(state, newObj) // ✅ 必須用這種方式
其實大多的情況工程師都會用ref,但有些特定的物件結構就可以使用reactive喔!!
Day1~Day5 奠定了「互動前端」的基礎。
下一步的魔法修煉 建議循序:
資料與後端溝通:確保資料可長期保存並維護。
組件化與架構:讓程式碼易於維護與擴充。
集中狀態管理:處理大型應用的複雜資料流。
其實要先學哪一個階段我認為都沒有固定的順序
不過通常我會覺得跟大概會這樣想,或是三種一起學也可以!!
1.如果你前端可以不用存data在資料庫資料庫的簡單api 或是一次性app (計算機、統計小工具),可以先pass
2.如果你不喜歡重工跟團隊合作的工程師,那我會建議一定先學這條路
3.如果在大型的app應用裡面,你不希望重工部分資料,這時候就會使用這個方式
就像你在學習魔法的時候我可以依照自己想要攻擊就先學攻擊力強的魔法,如果是輔助/治療可以轉成僧侶!?