iT邦幫忙

2025 iThome 鐵人賽

DAY 12
0

前言

接下來我們會開始建立 Nuxt 專案,Nuxt 是不需付費的開源框架基於 Vue.js 打造,能用來開發安全、快速且適合正式上線使用的網頁應用程式和網站。——參考來源 Nuxt 官方文件
Nuxt專案主要是以 .vue 檔案去做撰寫開發,而 Vue 是 Nuxt 的核心技術之一。因此在這個篇章,我們會先從 Vue 的基本語法與核心概念開始介紹,讓後面開始開發專案時能更加順手、上手更快🙌。

Vue 的基礎特性

  • 資料與 DOM 解耦:Vue 透過響應式系統和高效的渲染機制,將資料狀態與頁面呈現分離。它幫我們封裝了繁瑣的 DOM 操作,讓開發者能專注於處理資料與邏輯。
  • 元件化開發:透過 .vue 檔案可以將模板、邏輯和樣式封裝成單一元件檔案(SFC, Single File Component),讓開發與維護能更具結構,便於複用與維護。
  • 響應式資料綁定:可透過 v-model 實現雙向綁定,或使用插值語法 {{ }} 顯示資料。
  • 條件與列表渲染:像是 v-if、v-show、v-for 等指令可以動態控制畫面顯示內容。
  • 事件監聽:使用 @事件名稱(例如 @click)就能綁定 DOM 事件,處理使用者互動,並支援事件修飾符(例如 .stop、.prevent)來簡化事件行為控制。

Vue 生命週期

每一個 Vue 實例(Vue Instance)所經歷的生命週期,從創建到銷毀的整個過程,過程主要分為四個階段:創建、掛載、更新和銷毀。
Vue 3 提供了一系列的生命週期鉤子函式(Lifecycle Hooks)會在不同階段觸發,讓我們可以針對每個階段執行特定的操作,例如 初始化資料、渲染畫面或清除資源等。

生命週期流程圖

生命週期流程圖
(生命週期流程圖 圖片來源)

對於剛開始接觸 Vue 3 的朋友來說,可能會對兩種不同API風格的鉤子函式和生命週期名稱感到些許混淆,只要了解 Vue 有兩種撰寫風格:「選項式 API(Options API)」與「組合式 API(Composition API)」,就可以解開這個疑惑,我們會在下一篇詳細介紹這兩種 API 的差異與寫法。透過下方的對照表,快速掌握兩種API風格在四個主要階段(創建、掛載、更新、銷毀)中對應的寫法 👇:

階段 Options API 生命週期鉤子 (Hook) 名稱 Composition API 生命週期鉤子 (Hook) 名稱 補充說明
創建階段 beforeCreate、created 無對應,直接撰寫在 setup() 中。 在創建階段,beforeCreate 實例剛初始化,資料與方法尚未可用;created 以及 setup() 代表元件實例已完成建立,但未掛載至 DOM。
掛載階段 beforeMount、mounted onBeforeMount()、onMounted() 掛載階段包含 beforeMount、onBeforeMount() 是掛載前;mounted、onMounted() 掛載後。其中 mounted、onMounted() 執行時 DOM 已建立完成,適合進行 DOM 操作。在伺服器端渲染(SSR, Server side render)時不會被調用。
更新階段 beforeUpdate、updated onBeforeUpdate()、onUpdated() 在更新階段,每當 reactive 資料更新時觸發。beforeUpdate、onBeforeUpdate 在 DOM 更新之前執行;updated、onUpdated 執行時 DOM 已根據變化完成更新,因此可用於需要操作最新 DOM 的情境。在伺服器端渲染(SSR, Server side render)時不會被調用。
銷毀階段 beforeUnmount、unmounted onBeforeUnmount()、onUnmounted() 在銷毀階段,beforeUnmount、onBeforeUnmount 在元件即將卸載前執行,unmounted、onUnmounted 在卸載完成後執行,可以用於釋放資源、清除定時器與移除事件監聽等。在伺服器端渲染(SSR, Server side render)時不會被調用。

(參考來源 options API生命週期、 composition API生命週期)

Composition API 中 setup() 可以視為是整個「 beforeCreate + created 」的合併版本,因為它在元件實例還沒建立時就先執行了。以上分享了生命週期鉤子函式(Lifecycle Hooks)各階段,之後接手或參與Vue專案也可以透過觀察檔案裡的程式碼,去判斷這個 Vue 專案是採用哪一種 API 風格撰寫哦!

單一元件檔案(SFC, Single File Component)

在 Vue 中開發功能元件時,通常會使用到單一元件檔案(Single File Components),簡稱 SFC。

  • 檔案中將邏輯( JavaScript )、模板( HTML)、樣式(CSS)整合封裝在同一個 .vue 檔案中。每個 SFC 的區塊結構,通常會包含三種元素標籤:<script>、<template>、<style>這三個區塊都是選填的,並非每個檔案都需要同時存在,例如 像撰寫 composable function 時,可能就不會包含 <template> 區塊,因為它僅負責邏輯功能,不涉及畫面結構。但一個檔案裡至少需要包含一個 <template> 或 <script>元素。
<template>
  <!-- 模板區:負責畫面結構 -->
</template>

<script>
  // 腳本區:放資料、邏輯運算。
</script>

<script setup>
  // 腳本區:放資料、邏輯運算,使用 Composition API 的簡化語法。
</script>

<style scoped>
  /* 樣式區:設定動畫、顏色、尺寸等樣式,可加上 scoped 屬性局部套用 */
</style>

✦ 各區塊其他介紹:

  • <template> :這個區塊主要撰寫畫面的結構與 HTML 標籤,整份檔案可選擇不使用,若要使用最多只允許一個 <template> 區塊。
  • <script>、<script setup>:這兩個腳本區塊會以 ES 模組方式執行,其中 <script setup> 是專為 Composition API 而設計的簡化語法,可以讓頂層聲明的變數、函式與import的內容自動暴露給 <template>使用,不需要再使用 return。更多 <script setup> 詳細說明可參考官方文件,整份檔案可以同時存在 <script> 和 <script setup>,但各限一個。
  • <style>:用來撰寫樣式,可透過 scoped 或 module 屬性進行樣式封裝,並且可以在同一個元件中混合使用不同封裝模式的多個 <style> 區塊,整份檔案可以包含多個。

常用的模板語法與指令

在 Vue 中,指令的前方有 v- 作為前綴,用來標示這些是 Vue 提供的特殊指令,也就是我們在模板語法(template syntax)中常使用的,給 DOM 元素加上 Vue 特殊的行為。
接下來,我們來認識幾種常見的資料綁定方式,以及在 <template> 區塊中如何運用這些指令,將資料有效地渲染到畫面上🎨。

文本插值

當需要將資料插入文字或段落元素裡,例如 <p>、<div> ,可以使用 {{}} 花括號進行插值綁定。

<p>{{ name }}</p>

插入HTML區塊(v-html)

如果要插入一段 HTML,可以使用 v-html 指令。但這邊要特別注意 ⚠!這可能造成跨站腳本攻擊(XSS, Cross Site Scripting)風險,請不要直接使用未處理過的使用者輸入,請務必先進行內容安全處理與解析。

<div v-html="htmlContent"></div>

表單欄位(v-model)

  • 如果是想在輸入欄位加上值,並且實現響應式變化,可以使用 v-model實現雙向資料綁定,它幫我們完成了值綁定 (value binding) 與事件監聽 (event listener)。
<input v-model="userName" placeholder="請輸入姓名" />
  • 如果需要多行文字輸入顯示可以使用 <textarea>
<textarea v-model="note" placeholder="請輸入備註"></textarea>
  • 單選選項(Radio)
<div>選中的付款方式:{{ paymentMethod }}</div>

<input type="radio" id="credit" value="信用卡" v-model="paymentMethod" />
<label for="credit">信用卡</label>

<input type="radio" id="paypal" value="PayPal" v-model="paymentMethod" />
<label for="paypal">PayPal</label>

<input type="radio" id="atm" value="ATM轉帳" v-model="paymentMethod" />
<label for="atm">ATM轉帳</label>
  • 多選選項(Checkbox)
<div>被選中的水果:{{ favoriteFruits }}</div>

<input type="checkbox" id="apple" value="蘋果" v-model="favoriteFruits" />
<label for="apple">蘋果</label>

<input type="checkbox" id="banana" value="香蕉" v-model="favoriteFruits" />
<label for="banana">香蕉</label>

<input type="checkbox" id="cherry" value="櫻桃" v-model="favoriteFruits" />
<label for="cherry">櫻桃</label>
  • 如果需要點擊按鈕觸發其他事件,可以使用 v-on:click,v-on:的部份可以縮寫成@,簡寫為 @click:
<button type="button" @click="confirmButton">點擊</button>
  • 表單送出要阻止表單的預設行為,在Vue專案裡可以使用 .prevent 修飾符,避免瀏覽器預設提交跳頁行為,Vue 已封裝好 preventDefault()。
<form @submit.prevent="processSubmit">
  <input v-model="username" />
  <button type="submit">Submit</button>
</form>

更多的修飾符資訊與表單用法可參考官方文件

(參考來源 Vue.js 表單欄位)

屬性綁定(v-bind)

v-bind 可將資料綁定至元素屬性(attribute)上,例如 src、alt、class、style 等。也可以綁字串還可以直接傳陣列或物件,讓你動態組合多個 class 或 style。它會用 JavaScript 的 in 來檢查該 DOM 物件上有沒有同名的 DOM property,如果有,Vue 會優先把資料塞到 property 裡,而不是單純修改 HTML 屬性。v-bind 可以縮寫成 :。

<img :src="imgUrl" alt="圖片替代文字" / >

在Vue版本3.4以上「屬性名稱」跟「變數名稱」相同時,例如 <img :src="src" :alt="alt" /> 可以進一步簡化為省略值寫成:

<img :src :alt />

在專案中如果看到這樣的寫法,可以立即判斷專案是 Vue 3.4+ 以上版本。省略重複資訊降低了因變數命名錯誤(例如 打錯值、多加一個 s 😅)所造成的出錯率。同時,語意讀取速度也更快,大腦能直接辨識「原來只綁定了 src、alt 兩個屬性」,讓程式碼更直觀易懂。

清單渲染(v-for)

v-for 是 Vue 的迴圈指令,用來重複渲染列表資料。

<ul>   
  <li v-for="item in list" :key="item.id">{{ item.name }}</li>
</ul>

除了 in,也可以用 of 語法。

v-for="item of list"

條件判斷(v-if 與 v-show)

使用 v-if 可根據條件是否成立,決定是否渲染對應的模板區塊,如果初始時條件就不成立,則 DOM 元素、組件及其生命週期都不會建立。
當 data 有值時,顯示 <table> 區塊;data 為 falsy(例如 undefined、false 等)時,則顯示 v-else 無任何資訊區塊。

<table :data v-if="data"> 
   <!-- 資料表內容 -->
</table>
<div v-else>
  <p>無任何資訊</p>
</div>

搭配前面提到的 v-for,這邊要特別注意 ⚠! v-for 和 v-if 不建議寫在同一個元素上。
因為執行順序會先判斷 v-if 再執行 v-for,若 v-if 中的判斷條件依賴 v-for 內部的變數,容易因為變數尚未定義而導致錯誤。
可先透過 computed 屬性預先處理條件篩選,再交由 v-for 渲染,避免在 template 內混用複雜邏輯,其他更詳細的介紹可參考官方文件。

v-show是用來控制元素是否可見,若不可見只是被 display: none 隱藏,並不會銷毀 DOM。

<p v-show="isVisible">這是一段說明文字。</p>

如果條件判斷邏輯較為複雜,建議先透過 computed 計算屬性整理判斷條件,讓 template 維持乾淨、可讀性更高。
以下整理一份重點表格,幫助大家快速理解 v-if 與 v-show 之間的差異,並在實務上更容易判斷使用情境:

v-if vs v-show 快速對照

v-if v-show
控制是否建立 DOM 控制是否顯示 (切換 CSS display)
建立與銷毀成本高(例如 新建 DOM 、執行監聽器、初始化子元件 等) 切換顯示成本低(僅切換 CSS display)
適合不常切換變動的顯示內容 適合頻繁切換的 UI 顯示/隱藏內容

✍簡單記口訣:v-if 控制「是否建立」;v-show 控制「是否顯示」。

更多 v- 指令的使用方式,可以參考官方文件。

(參考來源 Vue.js 內建指令)

結語

以上整理了 Vue 核心觀念與常見語法的入門重點,雖然只是冰山一角,但已開始為後續開發建立基礎囉。當然還有很多值得分享的部份,推薦大家有空可以多逛逛官方網站,或許可以發現一些版本更新後新推出的實用特性。
Nuxt 是建立在 Vue 基礎之上的進階框架,未來開發中會不斷與這些核心觀念交會,因此越熟悉 Vue,就越能得心應手。
下一篇會詳細介紹 Vue 提供的兩種 API 風格(Options API 與 Composition API),說明它們的設計思維、使用差異,並分享在實務開發中該如何做出選擇。

參考資料與延伸閱讀

⑴ Nuxt 官方文件
⑵ Vue.js Lifecycle Hooks
⑶ Composition API 生命週期
⑷ Options API 生命週期
⑸ Vue.js script setup 參考來源
⑹ Vue.js SFC 規範
⑺ Vue.js template
⑻ Vue.js 表單欄位
⑼ Vue.js 內建指令


上一篇
11 如何將 Figma 設計轉換為 Tailwind + Vue 元件規劃
下一篇
13 Vue 3 兩種 API 寫法一次搞懂:Options vs Composition 怎麼選?
系列文
設計 x 開發:從 Figma 到 Vue,打造 LINE 互動形象網站! 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言