Vue 3 Composition API
Vue 3 的 Composition API 為開發者帶來了全新的程式碼組織方式,相較於 Options API,它提供更好的程式碼重用性和可維護性。本文將深入介紹 Composition API 的核心概念和使用方法,從基礎設定到進階應用,幫助你掌握這個強大的功能。無論你是 Vue 新手或是想轉換到 Composition API 的開發者,都能從本文獲得完整的學習指引。
目錄
- 重點整理
- Vue3 Composition API 注意事項
- Option API vs Composition API 計數器範例
- Composition API 中應避免的寫法
- 定義參數型別(Props)傳入子組件
- Ref 與 Reactive 的響應式資料
- Ref 與 Reactive 的差異
- Computed 計算屬性
- 撰寫 Composition API 的最佳實踐
重點整理
本文重點整理如下
- Composition API 的基本概念與優勢,包括更好的程式碼組織和重用性
- Option API 與 Composition API 的差異比較和使用場景
- ref 與 reactive 響應式資料的特性與使用方法
- Props 參數型別定義和傳遞方式
- computed 計算屬性的實作和最佳實踐
- 完整的程式碼撰寫規範和建議
- 實用的程式碼範例和使用情境說明
1. Vue3 Composition API 注意事項
Composition API 是 Vue 3 中引入的全新設計,它主要用於提升程式碼的可讀性與重用性,特別是當專案規模變大時。與 Option API 相比,Composition API 可以將邏輯更清晰地分割,同時避免了傳統 API 中模組化不易的問題。因此,這裡將探討 Composition API 的基本特性、優勢及其使用時的注意事項。
Composition API 的基本特性與優勢
- 模組化重用性:Composition API 支援將函式獨立封裝,便於不同元件間共享邏輯,減少重複程式碼。
- 響應式資料的靈活使用:透過
ref與reactive,可以簡單地定義和操作響應式資料,實現更靈活的資料管理。 - 生命周期函式更集中:使用
onMounted等方法,讓各階段的初始化邏輯集中在setup函式中,使邏輯更為集中清晰。
使用 Composition API 的最佳時機
- 元件邏輯複雜:當元件內有多個功能模組時,使用 Composition API 可避免邏輯分散,增強可讀性。
- 邏輯重用需求高:例如多個元件需要共享某些功能邏輯時,透過 Composition API 來提取函式實現重用會更有效。
- 元件規模較大:Composition API 更適合大型專案中組織程式碼,改善專案可維護性。
以下是使用 Composition API 的一個基礎範例,展示了如何使用 ref 定義響應式資料,並使用 onMounted 進行初始化設定。
基礎範例:簡單的計數器
這是一個 使用 Composition API 的計數器範例。透過 ref 宣告 count 變數,使其成為響應式資料,並在 setup 函式中完成邏輯設定。
<script setup>
import { ref, onMounted } from "vue";
// 定義響應式變數
const count = ref(0);
// 定義增加計數的函式
const increment = () => {
count.value += 1;
};
// 使用 onMounted 進行初始設定
onMounted(() => {
console.log(`初始化計數值:${count.value}`);
});
</script>
<template>
<div>VueCompositionAPI:{{ count }}</div>
<button @click="increment">Count is: {{ count }}</button>
</template>
在這個範例中:
- 響應式變數
count:使用ref定義,使變數能夠隨著數值變動而即時更新畫面。 - 計數函式
increment:直接操作count.value,藉此更新響應式資料。 onMounted初始設定:用於組件掛載後執行的邏輯,這裡透過console.log輸出初始的count值。
這個範例展示了 Composition API 的基本使用方式,也凸顯了 Vue 3 對於模組化邏輯的支持。Composition API 的靈活性不僅讓程式碼更具組織性,也提升了開發效率。
2. Option API vs Composition API 計數器範例
Vue 3 支援兩種不同的 API(Option API 和 Composition API),讓開發者能根據需求選擇更合適的寫法。這裡將介紹兩種 API 寫法的區別,並透過計數器範例比較它們的用法。
Option API 計數器寫法
Option API 是 Vue 2 中常用的方式,程式碼由 data、methods、computed 等選項組成,將邏輯依功能分區,易於理解,但不夠靈活。
以下是使用 Option API 的計數器範例:
<script>
export default {
data() {
return {
count: 0, // 定義計數器變數
};
},
methods: {
increment() { // 定義增加計數的函式
this.count++;
},
},
mounted() { // 使用 mounted 進行初始化設定
console.log(`初始計數值:${this.count}`);
},
};
</script>
<template>
<div>Vue:{{ count }}</div>
<button @click="increment">Count is: {{ count }}</button>
</template>
在這個範例中:
data:將count定義為組件的狀態變數。methods:將increment方法定義在methods中。mounted:在組件掛載時顯示初始值。
這種寫法的優點在於結構清晰,適合簡單的元件。但是當邏輯變得複雜且需要重用時,Option API 可能導致程式碼分散。
Composition API 計數器寫法
Composition API 是 Vue 3 引入的,允許將資料、方法、生命週期等集中在 setup 函式中。這種寫法使得邏輯更容易重用,適合大型應用程式。
以下是相同的計數器範例,使用 Composition API 來實現:
<script>
import { ref, onMounted } from "vue";
export default {
setup() {
const count = ref(0); // 使用 ref 宣告響應式變數
const increment = () => { // 定義計數增加的函式
count.value += 1;
};
onMounted(() => { // 使用 onMounted 取代 mounted 進行初始化
console.log(`初始計數值:${count.value}`);
});
return { count, increment }; // 將變數和函式回傳給 template 使用
},
};
</script>
<template>
<div>VueCompositionAPI:{{ count }}</div>
<button @click="increment">Count is: {{ count }}</button>
</template>
在這個 Composition API 的範例中:
ref:count變數透過ref進行響應式處理。這樣在畫面上count的變化會自動更新。onMounted:取代 Option API 中的mounted,直接在setup函式中初始化計數值。return:將count與increment返回給模板進行使用。
Composition API 的優勢在於結構的集中性和邏輯的靈活性。透過 setup 函式,資料與方法的集中管理讓重用更簡單,也提升了程式碼的可讀性和模組化。
結論
| API | 優勢 | 適合場合 |
|---|---|---|
| Option API | 結構清晰,易於理解 | 簡單的元件或小型專案 |
| Composition API | 高度模組化、便於重用及測試 | 複雜的邏輯或大型專案 |
在開發中,選擇使用 Option API 還是 Composition API 取決於專案的規模與需求。小型專案或簡單的邏輯可以使用 Option API,而大型專案則推薦使用 Composition API 來管理邏輯。透過兩種方式的結合,Vue 開發者可以靈活應對不同需求,實現更高效、可維護的程式碼。
3. Composition API 中應避免的寫法
在使用 Vue 3 Composition API 時,建議避免將 Option API 和 Composition API 的寫法混用,以保持程式碼風格的一致性與可讀性。特別是 setup 中的邏輯與生命週期方法(如 onMounted、onUnmounted 等),更應統一到 Composition API 的語法中,避免混用 mounted 等 Option API 方法,這樣能確保程式碼的易於維護性。
錯誤示範:混用 Composition API 與 Option API 的 mounted
在 Composition API 中,有些開發者可能會不小心將 mounted 直接寫入組件中,這樣的寫法會與 setup 內的 onMounted 發生衝突,影響程式碼的一致性。
以下是一個錯誤的範例,展示了如何混用 mounted 與 setup:
<script>
import { ref, onMounted } from "vue";
export default {
setup() {
const count = ref(0);
const increment = () => {
count.value += 1;
};
// 正確的使用方式:使用 onMounted 初始化資料
onMounted(() => {
console.log(`使用 onMounted:計數初始值為 ${count.value}`);
});
return { count, increment };
},
// 錯誤的使用方式:不應該在 Composition API 中混用 mounted
mounted() {
console.log(`錯誤的混用:計數初始值為 ${this.count}`);
},
};
</script>
<template>
<div>VueCompositionAPI:{{ count }}</div>
<button @click="increment">Count is: {{ count }}</button>
</template>
在這個範例中:
- 正確的寫法:應在
setup中使用onMounted來完成組件的掛載邏輯。 - 錯誤的寫法:在 Composition API 中添加
mounted,這會導致程式碼混亂且不一致。
正確示範:統一使用 Composition API 的生命週期函式
為了保持 Composition API 的一致性,建議在 setup 函式中使用 onMounted,並移除 mounted。如下所示:
<script>
import { ref, onMounted } from "vue";
export default {
setup() {
const count = ref(0);
const increment = () => {
count.value += 1;
};
// 使用 Composition API 的 onMounted 進行初始化
onMounted(() => {
console.log(`初始化計數值:${count.value}`);
});
return { count, increment };
},
};
</script>
<template>
<div>VueCompositionAPI:{{ count }}</div>
<button @click="increment">Count is: {{ count }}</button>
</template>
這樣的寫法在使用上更為一致,讓 setup 中的所有邏輯集中在 Composition API 中,減少錯誤發生的可能性。
混用 API 的潛在問題
混用 Option API 與 Composition API 會帶來一些問題:
- 程式碼可讀性降低:混用兩者會讓程式碼風格不統一,使其他開發者閱讀起來較為混亂。
- 維護困難:在大型專案中,保持 API 的一致性有助於維護和調試。如果混用,程式碼可能變得難以跟蹤。
- 生命週期函式不一致:Option API 中的
mounted與 Composition API 中的onMounted可能會執行重複或衝突的邏輯。
小結
在 Composition API 中,應避免使用 Option API 的方法,尤其是生命周期函式如 mounted。推薦統一使用 Composition API 的生命週期函式,例如 onMounted、onUnmounted 等,以提升程式碼的一致性與易於維護性。這樣的寫法能讓程式碼更具結構化,並減少潛在的錯誤風險。
4. 定義參數型別(Props)傳入子組件
在 Vue 中,將父組件的資料傳遞至子組件時,通常會使用 props。在 Vue 3 的 Composition API 中,props 的定義方式有所不同,特別是在使用 setup 語法糖的情況下。這裡將介紹如何在 Composition API 中正確定義 props 的型別,以及傳入子組件的資料類型。
定義 Props 的基本方法
在 Composition API 中,我們可以透過 defineProps 來設定 props 的型別和預設值。這讓組件更具自我描述性,尤其在多人協作和大型專案中,清晰的資料結構能夠提升維護效率。
不使用 Setup 語法糖的 Props 定義
在不使用 setup 語法糖的情況下,props 可以直接在 props 選項中定義其型別和預設值。以下範例展示了如何設定一個 data 物件作為 props 傳入子組件:
<script>
import { onMounted, ref } from "vue";
import HelloWorld from "../components/HelloWorld.vue";
export default {
components: {
HelloWorld,
},
props: {
data: { // 定義 data 的型別為 Object 並設置預設值
type: Object,
default: () => ({}),
},
},
setup(props) {
const count = ref(0);
const increment = () => {
count.value += 1;
};
onMounted(() => {
console.log(count.value);
});
return { count, increment };
},
};
</script>
<template>
<div>VueCompositionAPI:{{ count }}</div>
<button @click="increment">Count is: {{ count }}</button>
</template>
在這個範例中:
props選項:data被設置為一個Object,並有預設值{},可以讓子組件在沒有傳入參數時正常運行。props使用:在setup函式的參數中直接獲取props,可以進行相應的操作。
使用 Setup 語法糖的 Props 定義
使用 setup 語法糖可以讓程式碼更加簡潔 ,這時我們可以使用 defineProps 來設定 props。以下範例展示了相同的 data 物件,並使用 defineProps 來定義:
<script setup>
import { onMounted, ref } from "vue";
import HelloWorld from "../components/HelloWorld.vue";
// 使用 defineProps 定義 props 並設置預設值
const props = defineProps({
data: {
type: Object,
default: () => ({}),
},
});
const count = ref(0);
const increment = () => {
count.value += 1;
};
onMounted(() => {
console.log(count.value);
});
</script>
<template>
<div>VueCompositionAPI:{{ count }}</div>
<button @click="increment">Count is: {{ count }}</button>
</template>
在此範例中:
defineProps函式:將props直接定義於組件內,讓程式碼更簡潔,並能自動適應 TypeScript 等型別檢查工具。- 資料綁定:透過
props.data可以在組件中使用傳入的data資料,並且預設值為空物件{}。
使用 props 的最佳實踐
- 定義型別:對於
props的資料型別,應根據實際資料使用Object、Array、Number等具體型別,提升程式碼的自描述性。 - 設置預設值:使用
default為props設置預設值,以避免未傳入時造成的錯誤。 - 組件可讀性:使用
defineProps定義props時,更加簡潔的語法能提升組件的可讀性,適合大型專案中保持清晰的組件資料流。
這樣的寫法讓子組件在接收 props 時更具靈活性,同時使得 Composition API 的程式碼結構更為清晰簡單。