EP59 - 組件API的問與答

閱讀時間約 14 分鐘
Composition API FAQ,喔喔喔!問與答耶~
快來看看有什麼我內心的疑惑也有在裡頭~
但我都是太新手的疑惑居多 www
提示:本常見問題解答假設您對 Vue 有先前的經驗,特別是對於主要使用 Options API 的 Vue 2 版本的經驗。

什麼是 Composition API? - What is Composition API?

Composition API 是一組 API,允許我們使用導入的函數來編寫 Vue 組件,而不是宣告選項。它是一個總稱,涵蓋以下幾種 API:

  1. 反應性 API:例如 ref() 和 reactive(),允許我們直接創建反應性狀態、計算屬性和監視器。
  2. 生命週期鉤子:例如 onMounted() 和 onUnmounted(),允許我們以程式方式掛鉤到組件的生命週期中。
  3. 依賴注入:即 provide() 和 inject(),允許我們在使用反應性 API 時利用 Vue 的依賴注入系統。

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? - Why Composition API?

更好的邏輯重用 - Better Logic Reuse

Composition API 的主要優勢在於它能以可組合函數的形式實現乾淨、高效的邏輯重用。它解決了 Options API 的主要邏輯重用機制(混入)的所有缺點

Composition API 的邏輯重用能力促成了一些令人印象深刻的社群專案,如 VueUse,一個不斷增長的可組合工具集。此外,它還為將有狀態的第三方服務或庫(如不可變數據狀態機RxJS)輕鬆整合到 Vue 的反應性系統中提供了一個乾淨的機制。

更靈活的代碼組織 - More Flexible Code Organization

許多用戶喜歡我們使用 Options API 來編寫有組織的代碼:一切都根據其所屬的選項有其特定的位置。然而,當單個組件的邏輯超過一定的複雜度門檻時,Options API 就會帶來嚴重的限制。這種限制在需要處理多個邏輯關注點的組件中特別突出,我們在許多生產中的 Vue 2 應用中親眼目睹了這一點。

以 Vue CLI 的 GUI 中的資料夾瀏覽器組件為例:此組件負責以下邏輯關注點:

  • 跟蹤當前資料夾狀態並顯示其內容
  • 處理資料夾導航(打開、關閉、刷新...)
  • 處理新資料夾的創建
  • 切換顯示僅收藏資料夾
  • 切換顯示隱藏資料夾
  • 處理當前工作目錄變更

該組件的原始版本是使用 Options API 編寫的。如果我們根據邏輯關注點為每行代碼分配一個顏色,它看起來是這樣的:

raw-image

注意,處理相同邏輯關注點的代碼被迫分散在不同的選項中,位於文件的不同部分。在一個幾百行長的組件中,理解和導航單一的邏輯關注點需要不斷上下滾動文件,使得這個過程比應有的難得多。此外,如果我們打算將某個邏輯關注點提取為可重用的工具,從文件的不同部分找到並提取正確的代碼片段需要不少工作。

以下是同一組件在重構為 Composition API 前後的對比:

raw-image

注意,現在與相同邏輯關注點相關的代碼可以組合在一起:在處理特定邏輯關注點時,我們不再需要在不同的選項塊之間跳轉。此外,我們現在可以輕鬆地將一組代碼移動到外部文件,因為我們不再需要為了提取它們而重新安排代碼。這種減少重構摩擦的特性對大型代碼庫的長期可維護性至關重要。

更好的類型推斷 - Better Type Inference

近年來,越來越多的前端開發者採用 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 用戶可以受益於部分類型推斷。

更小的生產包和更少的開銷 - Smaller Production Bundle and Less Overhead

使用 Composition API 和 <script setup> 編寫的代碼比等效的 Options API 更高效且更適合壓縮。這是因為 <script setup> 組件中的模板被編譯為在 <script setup> 代碼的相同作用域內內聯的函數。與從 this 訪問屬性不同,編譯的模板代碼可以直接訪問在 <script setup> 中宣告的變量,而中間沒有實例代理。這也導致更好的壓縮效果,因為所有變量名稱都可以安全地縮短。

與 Options API 的關係 - Relationship with Options API

取捨 - Trade-offs

有些從 Options API 過渡到 Composition API 的用戶發現他們的 Composition API 代碼組織性較差,並認為 Composition API 在代碼組織方面「更糟糕」。我們建議這些用戶從不同的角度來看待這個問題。

確實,Composition API 不再提供「護欄」來引導您將代碼放入各自的框架中。相應地,您可以像編寫普通 JavaScript 一樣撰寫組件代碼。這意味著您可以並且應該將任何代碼組織最佳實踐應用於您的 Composition API 代碼,就像編寫普通 JavaScript 一樣。如果您能寫出組織良好的 JavaScript,您也應該能寫出組織良好的 Composition API 代碼。

Options API 確實允許您在撰寫組件代碼時「思考更少」,這也是為什麼許多用戶喜歡它。然而,在減少思維負擔的同時,它也將您鎖定在預設的代碼組織模式中,沒有退出機制,這可能使在大型項目中進行重構或提高代碼質量變得困難。就這方面而言,Composition API 提供了更好的長期可擴展性。

Composition API 覆蓋所有用例嗎? - Does Composition API cover all use cases?

在有狀態邏輯方面,答案是肯定的。使用 Composition API 時,只有幾個選項仍然需要:propsemitsnameinheritAttrs

小提示:自 3.3 版本起,您可以直接在 <script setup> 中使用 defineOptions 設置組件名或 inheritAttrs 屬性。

如果您打算專門使用 Composition API(以及上述選項),您可以通過編譯時標誌刪除 Vue 中的 Options API 相關代碼,從而減少幾個 KB 的生產包大小。請注意,這也會影響您的依賴項中的 Vue 組件。

可以在同一個組件中使用兩種 API 嗎? - Can I use both APIs in the same component?

可以。您可以通過 setup() 選項在 Options API 組件中使用 Composition API。

然而,我們只建議在需要與使用 Composition API 編寫的新功能/外部庫集成的現有 Options API 代碼庫中這樣做。

Options API 會被棄用嗎? - Will Options API be deprecated?

不,我們沒有這樣的計劃。Options API 是 Vue 的一個重要組成部分,許多開發者都喜歡它。我們也意識到 Composition API 的許多優點僅在大型項目中顯現,而 Options API 在許多低到中等複雜度的場景中仍然是穩健的選擇。

與 Class API 的關係 - Relationship with Class API

我們不再建議在 Vue 3 中使用 Class API,因為 Composition API 提供了出色的 TypeScript 集成以及額外的邏輯重用和代碼組織優勢。

與 React Hooks 的比較 - Comparison with React Hooks

Composition API 提供了與 React Hooks 相同級別的邏輯組合能力,但有一些重要的區別。

React Hooks 在每次組件更新時都會重複調用,這會導致許多容易混淆的情況,甚至連有經驗的 React 開發者也會困惑。這也會導致性能優化問題,嚴重影響開發體驗。以下是一些例子:

  • Hooks 對調用順序敏感,不能是條件式的。
  • React 組件中聲明的變量可能會被 Hook 閉包捕獲,並在開發者未能傳遞正確的依賴數組時變得「過時」。這使得 React 開發者依賴 ESLint 規則來確保傳遞了正確的依賴。然而,該規則通常不夠智能,過度補償正確性,導致不必要的無效化,並在遇到邊緣情況時頭痛。
  • 昂貴的計算需要使用 useMemo,這又需要手動傳遞正確的依賴數組。
  • 傳遞給子組件的事件處理程序默認會導致不必要的子更新,並需要顯式使用 useCallback 作為優化。這幾乎總是需要的,並且再次需要正確的依賴數組。忽視這一點會導致默認情況下過度渲染的應用程序,並可能在未意識到的情況下造成性能問題。
  • 過時的閉包問題,加上 Concurrent 特性,使得推理何時運行一段 hooks 代碼變得困難,並使得處理應在渲染之間持久化的可變狀態(通過 useRef)變得繁瑣。
注意:一些與記憶化相關的上述問題可以通過即將推出的 React 編譯器解決。

相比之下,Vue Composition API:

  • 只調用一次 setup()<script setup> 代碼。這使得代碼更符合 JavaScript 的直觀使用,因為不會有過時的閉包需要擔心。Composition API 調用也不對調用順序敏感,可以是條件式的。
  • Vue 的運行時響應系統自動收集在計算屬性和監聽器中使用的響應依賴,因此無需手動聲明依賴。
  • 無需手動緩存回調函數以避免不必要的子更新。一般來說,Vue 的細粒度響應系統確保子組件只在需要時更新。對 Vue 開發者來說,手動的子更新優化幾乎不是一個問題。

我們承認 React Hooks 的創意,並且它是 Composition API 的一個主要靈感來源。然而,這些設計中提到的問題確實存在,我們注意到 Vue 的響應模型恰好提供了一種解決這些問題的方法。

好像對組件API有更多瞭解了!!!
晚安摟~早點睡覺!!!
2會員
68內容數
分享生活趣事~
留言0
查看全部
發表第一個留言支持創作者!
卡關的人生 的其他內容
Vue 是一個靈活且可逐步採用的框架,適用於不同使用情境以平衡技術棧複雜度、開發者體驗和最終性能。Vue 可以作為獨立腳本文件使用,不需構建步驟,適合簡單前端邏輯。也可用來構建標準 Web 組件,嵌入到任何 HTML 頁面中。對於需要豐富互動性的應用,可構建單頁應用程式 (SPA)。
項目 API 涉及整體應用的全局屬性及配置,通常透過 TypeScript 的模組擴充來增強全局屬性,如 app.config.globalProperties。
在使用 Vue 組件 API 和 TypeScript 的開發中,通常會遇到類型錯誤和需要 debug 的情況。組件 API 下的 TypeScript 提供了更強的型別檢查和類型推斷功能,這有助於減少錯誤。
使用 TypeScript 開發 Vue 的好處包括:靜態類型檢查可減少運行時錯誤,提升代碼重構的安全性。TypeScript 提供更好的開發體驗,因為 IDE 支持類型自動完成功能。
允許未經過濾的使用者內容執行會帶來攻擊風險。建議參考 HTML5 Security Cheat Sheet 和 OWASP's XSS Prevention Cheat Sheet,並檢查依賴項源代碼是否存在危險模式。
網站可及性(a11y)是指創建任何人都能使用的網站,無論是殘障人士、網速緩慢的用戶、使用過時或損壞硬體的人,還是處於不利環境中的人。例如,為視頻添加字幕能幫助聾人和聽力受損者,也能幫助處於嘈雜環境中的人。設計考慮應包括色彩對比、字體選擇、文本大小和語言。
Vue 是一個靈活且可逐步採用的框架,適用於不同使用情境以平衡技術棧複雜度、開發者體驗和最終性能。Vue 可以作為獨立腳本文件使用,不需構建步驟,適合簡單前端邏輯。也可用來構建標準 Web 組件,嵌入到任何 HTML 頁面中。對於需要豐富互動性的應用,可構建單頁應用程式 (SPA)。
項目 API 涉及整體應用的全局屬性及配置,通常透過 TypeScript 的模組擴充來增強全局屬性,如 app.config.globalProperties。
在使用 Vue 組件 API 和 TypeScript 的開發中,通常會遇到類型錯誤和需要 debug 的情況。組件 API 下的 TypeScript 提供了更強的型別檢查和類型推斷功能,這有助於減少錯誤。
使用 TypeScript 開發 Vue 的好處包括:靜態類型檢查可減少運行時錯誤,提升代碼重構的安全性。TypeScript 提供更好的開發體驗,因為 IDE 支持類型自動完成功能。
允許未經過濾的使用者內容執行會帶來攻擊風險。建議參考 HTML5 Security Cheat Sheet 和 OWASP's XSS Prevention Cheat Sheet,並檢查依賴項源代碼是否存在危險模式。
網站可及性(a11y)是指創建任何人都能使用的網站,無論是殘障人士、網速緩慢的用戶、使用過時或損壞硬體的人,還是處於不利環境中的人。例如,為視頻添加字幕能幫助聾人和聽力受損者,也能幫助處於嘈雜環境中的人。設計考慮應包括色彩對比、字體選擇、文本大小和語言。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
如何在 Vite 專案中安裝和設置 TypeScript 及路徑別名的步驟,包括安裝必要的依賴、配置 vite.config.js、tsconfig.json 的設置,及如何創建類型聲明文件來正確識別 .vue 文件。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
※ 什麼是Web API API 就是後端開出來讓前端來用的介面,讓前端與後端可以溝通。 API流程: 終端使用者用任何一種裝置進入瀏覽器。 瀏覽器透過 API 向後端發出請求,請求查詢或修改資料。 後端透過 API 收到前端的請求後,取得資料並回應給前端。 前端渲染畫面,終端使用者
Thumbnail
Quasar Dialog 的 Invoking custom component 很好用,但是有些困擾的地方,一起來看看有甚麼辦法吧。
Thumbnail
在本章節中,我們探討了 PHP 中如何引用和管理套件。學習了如何使用 Composer 來安裝第三方套件,以及如何引用自定義模組。此外,我們還介紹了如何創建和使用自定義套件,並列舉了一些在 PHP 社群中常見且廣泛使用的套件和庫。通過掌握這些知識,開發者可以更有效地管理和利用各種資源。
Thumbnail
一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
我們在實作中,難免會遇到在不同組件中,卻有需求相同的資料格式,因此 mixins 可以達到我們的需求,除了 data 以外也包含了 methods 可以共用,舉例來說,學生資料可能會在,班級跟社團內被使用,當我們要撰寫元件時,就可以省略多餘的 data 定義。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
如何在 Vite 專案中安裝和設置 TypeScript 及路徑別名的步驟,包括安裝必要的依賴、配置 vite.config.js、tsconfig.json 的設置,及如何創建類型聲明文件來正確識別 .vue 文件。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
※ 什麼是Web API API 就是後端開出來讓前端來用的介面,讓前端與後端可以溝通。 API流程: 終端使用者用任何一種裝置進入瀏覽器。 瀏覽器透過 API 向後端發出請求,請求查詢或修改資料。 後端透過 API 收到前端的請求後,取得資料並回應給前端。 前端渲染畫面,終端使用者
Thumbnail
Quasar Dialog 的 Invoking custom component 很好用,但是有些困擾的地方,一起來看看有甚麼辦法吧。
Thumbnail
在本章節中,我們探討了 PHP 中如何引用和管理套件。學習了如何使用 Composer 來安裝第三方套件,以及如何引用自定義模組。此外,我們還介紹了如何創建和使用自定義套件,並列舉了一些在 PHP 社群中常見且廣泛使用的套件和庫。通過掌握這些知識,開發者可以更有效地管理和利用各種資源。
Thumbnail
一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
我們在實作中,難免會遇到在不同組件中,卻有需求相同的資料格式,因此 mixins 可以達到我們的需求,除了 data 以外也包含了 methods 可以共用,舉例來說,學生資料可能會在,班級跟社團內被使用,當我們要撰寫元件時,就可以省略多餘的 data 定義。