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-ifv-showv-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) 名稱 補充說明
創建階段 beforeCreatecreated 無對應,直接撰寫在 setup() 中。 在創建階段,beforeCreate 實例剛初始化,資料與方法尚未可用;created 以及 setup() 代表元件實例已完成建立,但未掛載至 DOM。
掛載階段 beforeMountmounted onBeforeMount()onMounted() 掛載階段包含 beforeMountonBeforeMount() 是掛載前;mountedonMounted() 掛載後。其中 mounted、onMounted() 執行時 DOM 已建立完成,適合進行 DOM 操作。在伺服器端渲染(SSR, Server side render)時不會被調用。
更新階段 beforeUpdateupdated onBeforeUpdate()onUpdated() 在更新階段,每當 reactive 資料更新時觸發。beforeUpdateonBeforeUpdate 在 DOM 更新之前執行;updatedonUpdated 執行時 DOM 已根據變化完成更新,因此可用於需要操作最新 DOM 的情境。在伺服器端渲染(SSR, Server side render)時不會被調用。
銷毀階段 beforeUnmountunmounted onBeforeUnmount()onUnmounted() 在銷毀階段,beforeUnmountonBeforeUnmount 在元件即將卸載前執行,unmountedonUnmounted 在卸載完成後執行,可以用於釋放資源、清除定時器與移除事件監聽等。在伺服器端渲染(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>:用來撰寫樣式,可透過 scopedmodule 屬性進行樣式封裝,並且可以在同一個元件中混合使用不同封裝模式的多個 <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)上,例如 srcaltclassstyle 等。也可以綁字串還可以直接傳陣列或物件,讓你動態組合多個 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-forv-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-ifv-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 互動形象網站!26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言