接下來我們會開始建立 Nuxt 專案,Nuxt 是不需付費的開源框架基於 Vue.js 打造,能用來開發安全、快速且適合正式上線使用的網頁應用程式和網站。——參考來源 Nuxt 官方文件
Nuxt專案主要是以 .vue
檔案去做撰寫開發,而 Vue 是 Nuxt 的核心技術之一。因此在這個篇章,我們會先從 Vue 的基本語法與核心概念開始介紹,讓後面開始開發專案時能更加順手、上手更快🙌。
.vue
檔案可以將模板、邏輯和樣式封裝成單一元件檔案(SFC, Single File Component),讓開發與維護能更具結構,便於複用與維護。v-model
實現雙向綁定,或使用插值語法 {{ }}
顯示資料。v-if
、v-show
、v-for
等指令可以動態控制畫面顯示內容。@事件名稱
(例如 @click
)就能綁定 DOM 事件,處理使用者互動,並支援事件修飾符(例如 .stop
、.prevent
)來簡化事件行為控制。每一個 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 風格撰寫哦!
在 Vue 中開發功能元件時,通常會使用到單一元件檔案(Single File Components),簡稱 SFC。
.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
指令。但這邊要特別注意 ⚠!這可能造成跨站腳本攻擊(XSS, Cross Site Scripting)風險,請不要直接使用未處理過的使用者輸入,請務必先進行內容安全處理與解析。
<div v-html="htmlContent"></div>
v-model
實現雙向資料綁定,它幫我們完成了值綁定 (value binding) 與事件監聽 (event listener)。<input v-model="userName" placeholder="請輸入姓名" />
<textarea>
<textarea v-model="note" placeholder="請輸入備註"></textarea>
<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>
<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>
.prevent
修飾符,避免瀏覽器預設提交跳頁行為,Vue 已封裝好 preventDefault()
。<form @submit.prevent="processSubmit">
<input v-model="username" />
<button type="submit">Submit</button>
</form>
更多的修飾符資訊與表單用法可參考官方文件
(參考來源 Vue.js 表單欄位)
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
是 Vue 的迴圈指令,用來重複渲染列表資料。
<ul>
<li v-for="item in list" :key="item.id">{{ item.name }}</li>
</ul>
除了 in
,也可以用 of
語法。
v-for="item of list"
使用 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 | 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 內建指令