Composition API FAQ,喔喔喔!問與答耶~
快來看看有什麼我內心的疑惑也有在裡頭~
但我都是太新手的疑惑居多 www
提示:本常見問題解答假設您對 Vue 有先前的經驗,特別是對於主要使用 Options API 的 Vue 2 版本的經驗。
Composition API 是一組 API,允許我們使用導入的函數來編寫 Vue 組件,而不是宣告選項。它是一個總稱,涵蓋以下幾種 API:
Composition API 是 Vue 3 和 Vue 2.7 的內建功能。對於舊的 Vue 2 版本,可以使用官方維護的 @vue/composition-api
插件。在 Vue 3 中,它主要與單文件組件中的 <script setup>
語法一起使用。以下是一個使用 Composition API 的基本範例:
<script setup>
import { ref, onMounted } from 'vue'
// 反應性狀態
const count = ref(0)
// 修改狀態並觸發更新的函數
function increment() {
count.value++
}
// 生命週期鉤子
onMounted(() => {
console.log(`The initial count is ${count.value}.`)
})
</script>
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>
儘管 Composition API 的風格基於函數組合,它並不是函數式編程。Composition API 基於 Vue 的可變、細粒度的反應性範式,而函數式編程則強調不可變性。
Composition API 的主要優勢在於它能以可組合函數的形式實現乾淨、高效的邏輯重用。它解決了 Options API 的主要邏輯重用機制(混入)的所有缺點。
Composition API 的邏輯重用能力促成了一些令人印象深刻的社群專案,如 VueUse,一個不斷增長的可組合工具集。此外,它還為將有狀態的第三方服務或庫(如不可變數據、狀態機和 RxJS)輕鬆整合到 Vue 的反應性系統中提供了一個乾淨的機制。
許多用戶喜歡我們使用 Options API 來編寫有組織的代碼:一切都根據其所屬的選項有其特定的位置。然而,當單個組件的邏輯超過一定的複雜度門檻時,Options API 就會帶來嚴重的限制。這種限制在需要處理多個邏輯關注點的組件中特別突出,我們在許多生產中的 Vue 2 應用中親眼目睹了這一點。
以 Vue CLI 的 GUI 中的資料夾瀏覽器組件為例:此組件負責以下邏輯關注點:
該組件的原始版本是使用 Options API 編寫的。如果我們根據邏輯關注點為每行代碼分配一個顏色,它看起來是這樣的:
注意,處理相同邏輯關注點的代碼被迫分散在不同的選項中,位於文件的不同部分。在一個幾百行長的組件中,理解和導航單一的邏輯關注點需要不斷上下滾動文件,使得這個過程比應有的難得多。此外,如果我們打算將某個邏輯關注點提取為可重用的工具,從文件的不同部分找到並提取正確的代碼片段需要不少工作。
以下是同一組件在重構為 Composition API 前後的對比:
注意,現在與相同邏輯關注點相關的代碼可以組合在一起:在處理特定邏輯關注點時,我們不再需要在不同的選項塊之間跳轉。此外,我們現在可以輕鬆地將一組代碼移動到外部文件,因為我們不再需要為了提取它們而重新安排代碼。這種減少重構摩擦的特性對大型代碼庫的長期可維護性至關重要。
近年來,越來越多的前端開發者採用 TypeScript,因為它有助於我們編寫更健壯的代碼,讓我們更有信心地進行更改,並通過 IDE 支持提供良好的開發體驗。然而,最初在 2013 年設計的 Options API 沒有考慮到類型推斷。我們必須實現一些極其複雜的類型體操來使類型推斷與 Options API 一起工作。即使做了這麼多努力,Options API 的類型推斷在面對混入和依賴注入時仍可能崩潰。
這導致許多希望與 TS 一起使用 Vue 的開發者傾向於使用由 vue-class-component
提供支持的 Class API。然而,基於類的 API 嚴重依賴於 ES 裝飾器,這是一個在 2019 年 Vue 3 開發時僅處於第 2 階段提案的語言功能。我們認為基於一個不穩定的提案來設計官方 API 風險太大。從那時起,裝飾器提案經歷了又一次徹底改革,並在 2022 年最終達到了第 3 階段。此外,基於類的 API 在邏輯重用和組織方面也有類似於 Options API 的限制。
相比之下,Composition API 主要使用普通變量和函數,這些都是自然類型友好的。使用 Composition API 編寫的代碼可以享受完整的類型推斷,幾乎不需要手動類型提示。大多數情況下,Composition API 代碼在 TypeScript 和普通 JavaScript 中看起來幾乎相同。這也使得普通 JavaScript 用戶可以受益於部分類型推斷。
使用 Composition API 和 <script setup>
編寫的代碼比等效的 Options API 更高效且更適合壓縮。這是因為 <script setup>
組件中的模板被編譯為在 <script setup>
代碼的相同作用域內內聯的函數。與從 this
訪問屬性不同,編譯的模板代碼可以直接訪問在 <script setup>
中宣告的變量,而中間沒有實例代理。這也導致更好的壓縮效果,因為所有變量名稱都可以安全地縮短。
有些從 Options API 過渡到 Composition API 的用戶發現他們的 Composition API 代碼組織性較差,並認為 Composition API 在代碼組織方面「更糟糕」。我們建議這些用戶從不同的角度來看待這個問題。
確實,Composition API 不再提供「護欄」來引導您將代碼放入各自的框架中。相應地,您可以像編寫普通 JavaScript 一樣撰寫組件代碼。這意味著您可以並且應該將任何代碼組織最佳實踐應用於您的 Composition API 代碼,就像編寫普通 JavaScript 一樣。如果您能寫出組織良好的 JavaScript,您也應該能寫出組織良好的 Composition API 代碼。
Options API 確實允許您在撰寫組件代碼時「思考更少」,這也是為什麼許多用戶喜歡它。然而,在減少思維負擔的同時,它也將您鎖定在預設的代碼組織模式中,沒有退出機制,這可能使在大型項目中進行重構或提高代碼質量變得困難。就這方面而言,Composition API 提供了更好的長期可擴展性。
在有狀態邏輯方面,答案是肯定的。使用 Composition API 時,只有幾個選項仍然需要:props
、emits
、name
和 inheritAttrs
。
小提示:自 3.3 版本起,您可以直接在<script setup>
中使用defineOptions
設置組件名或inheritAttrs
屬性。
如果您打算專門使用 Composition API(以及上述選項),您可以通過編譯時標誌刪除 Vue 中的 Options API 相關代碼,從而減少幾個 KB 的生產包大小。請注意,這也會影響您的依賴項中的 Vue 組件。
可以。您可以通過 setup()
選項在 Options API 組件中使用 Composition API。
然而,我們只建議在需要與使用 Composition API 編寫的新功能/外部庫集成的現有 Options API 代碼庫中這樣做。
不,我們沒有這樣的計劃。Options API 是 Vue 的一個重要組成部分,許多開發者都喜歡它。我們也意識到 Composition API 的許多優點僅在大型項目中顯現,而 Options API 在許多低到中等複雜度的場景中仍然是穩健的選擇。
我們不再建議在 Vue 3 中使用 Class API,因為 Composition API 提供了出色的 TypeScript 集成以及額外的邏輯重用和代碼組織優勢。
Composition API 提供了與 React Hooks 相同級別的邏輯組合能力,但有一些重要的區別。
React Hooks 在每次組件更新時都會重複調用,這會導致許多容易混淆的情況,甚至連有經驗的 React 開發者也會困惑。這也會導致性能優化問題,嚴重影響開發體驗。以下是一些例子:
useMemo
,這又需要手動傳遞正確的依賴數組。useCallback
作為優化。這幾乎總是需要的,並且再次需要正確的依賴數組。忽視這一點會導致默認情況下過度渲染的應用程序,並可能在未意識到的情況下造成性能問題。useRef
)變得繁瑣。注意:一些與記憶化相關的上述問題可以通過即將推出的 React 編譯器解決。
相比之下,Vue Composition API:
setup()
或 <script setup>
代碼。這使得代碼更符合 JavaScript 的直觀使用,因為不會有過時的閉包需要擔心。Composition API 調用也不對調用順序敏感,可以是條件式的。我們承認 React Hooks 的創意,並且它是 Composition API 的一個主要靈感來源。然而,這些設計中提到的問題確實存在,我們注意到 Vue 的響應模型恰好提供了一種解決這些問題的方法。
好像對組件API有更多瞭解了!!!
晚安摟~早點睡覺!!!