Vue 3 提供 Option API 和 Composition API 兩種寫法,Option API 是延伸自 Vue 2 的寫法,Composition API 則是跟著 Vue 3 一起推出的新寫法。
Option API 和 Composition API 主要差別有兩個:
對新手來說,兩者最大的差別是管理程式碼的方式,這篇文章也會著重在這個部份。
註1:兩者主要是在邏輯區塊的寫法不同(也就是<script>
的部份),在模板和樣式的用法是一樣的。
註2:關於 Composables 的部份,會在最後稍微點到 Option API 在 「Composables」上的限制,但詳細內容會放在後面的篇章。
所謂的 Option (選項),就是 Vue 將程式碼根據特性不同,分類成資料(data)、方法(method)、計算屬性(computed)、生命週期......不同選項,讓開發者透過分別「宣告選項 (Option)」的方式,來定義元件內的邏輯。
舉例比較常用的 Option 如:
data
:用來宣告響應式資料的初始值
method
:用來宣告在元件中要使用的方法
computed
:回傳對資料的加工或計算結果
程式碼會根據選項 API 被分成幾個區塊,看起來像這樣:
export default {
//宣告響應式資料的初始值
data() {
return {
// 使用者資料
user: {
name: "unknown",
gender: "unknown",
isVIP: false,
},
// 訂購資訊
product: {
name: "keyboard",
quantity: 0,
price: 150,
},
// 彈跳視窗
isModalOpen: false,
};
},
//回傳對資料的加工或計算結果
computed: {
originalTotal() {
return this.quantity * this.price;
},
rewardPoints() {
return this.originalTotal * 0.01;
},
},
//宣告在元件中要使用的方法
methods: {
// 提交訂購
async handleSubmit() {
//略
},
// 開關彈跳視窗
toggleModal() {
this.isModalOpen = !this.isModalOpen;
},
},
};
在 Composition API 搭配 <script setup>
的情況下,可以將所有邏輯程式碼直接寫在 <script>
內,就跟寫原生 Javascript 的感覺很像,幾乎沒有什麼特殊規則,交由開發者自行管理。
使用 Composition API 時,通常會根據「功能」來分區管理程式碼,同個功能使用到的資料、方法,宣告位置可以比較靠近,對於大的、複雜的元件來說,會提升易讀性。
程式碼看起來可能會像這樣:
//搭配 <script setup>
import { computed, reactive, ref } from "vue";
const isModalOpen = ref(false);
function toggleModal() {
isModalOpen.value = !isModalOpen.value;
}
const user = reactive({
name: "unknown",
gender: "unknown",
isVIP: false,
});
const product = reactive({
name: "keyboard",
price: 150,
});
const quantity = ref(0);
const originalTotal = computed(() => quantity.value * product.price);
const rewardPoints = computed(() => originalTotal.value * 0.01);
async function handleSubmit() {
//提交訂單...
//提交訂單...
//提交訂單...
}
看一下兩個 API 的程式碼差異:
兩種方式都有人喜歡,沒有絕對的好壞。
其實「自由 / 彈性」在程式碼管理上是把雙面刃,更考驗開發者管理程式碼的能力;也有開發者偏好在訂好的規則下進行開發,兩者並沒有優劣,而是風格差異。
以 Vue 的響應式功能為例。
reactive()
和 ref()
定義資料是否有響應性,在其他地方取用資料時,也就要根據 reactive()
和 ref()
的規則進行取值和操作。data
回傳的資料加上響應性,其他選項要取用 data
內的資料時,用 this.變數名稱
取得即可。但整個兩者背後的響應式模組是一樣的,核心概念不變,而是根據 Vue 定義的寫法不同,有不同的使用方式,所以 Vue 官網將教學指南分成兩種 API 形式
範例:
以剛剛的程式碼來說,有一個彈跳視窗,由 isModalOpen
控制他是否開啟,由 toggleModal
這個 method 來切換他的狀態。
左邊 - Option API:彈跳視窗這個功能的邏輯,就會被拆散到 data
和 methods
兩個不同區塊。
右邊 - Composition API:我可以把彈跳視窗這個功能的邏輯放到同一個區塊,能更快找到相依的定義。
可以想像當元件越複雜,中間的程式碼會越來越多,就會像官網的圖一樣:
Option API 和 Composition API 的核心概念是共通的,而且 Vue 3 提供的開發功能都有涵蓋到兩種 API,只是用法上會有些許差異。
來看看 Vue 文件怎麼說:
两种 API 风格都能够覆盖大部分的应用场景。它们只是同一个底层系统所提供的两套不同的接口。实际上,选项式 API 是在组合式 API 的基础上实现的!关于 Vue 的基础概念和知识在它们之间都是通用的。
還有文件給新手的建議:
在学习的过程中,推荐采用更易于自己理解的风格。再强调一下,大部分的核心概念在这两种风格之间都是通用的。熟悉了一种风格以后,你也能够很快地理解另一种风格。
在一個 Vue 專案內是可以同時有這兩種 API 風格開發的元件,所以初學者可以都嘗試看看,選擇自己更喜歡的開始入手。
前面已經了解到,Option API 會將邏輯根據 Option 分開來定義,那如果今天我們想要複用一整組邏輯,邏輯裡面包含:資料(data)、方法(method)、計算屬性(computed)...不同的 Option,舉例如下:
function usePointCounter() {
const point = ref(0);
function plus() {
point.value++;
}
function minus() {
point.value--;
}
const performance = computed(() => (point > 100 ? "good" : "bad"));
return {
count: point,
plus,
minus,
performance,
};
}
如上,如果專案內有一組分數相關的邏輯處理,包含初始資料定義、方法和計算屬性。
Option API 在這類組合式函數(Composables)上有他的限制,這也是兩個 API 風格另一個差異。
引用到 Option API 元件內有不同作法,各有他的優缺點,這部份等到「Composables」篇章再來討論。