Skip to content

Vue 3 Composable 完全指南:如何開發可重複使用的邏輯函數?

Vue 3 組合函式介紹:composables 目錄與命名規範

在開發 Vue 應用程式時,是否常遇到邏輯重複、元件過於肥大的問題? Composable (組合式函數) 正是為了解決這些痛點而生。簡單來說,Composable 是將可重複使用的 狀態與行為 封裝成獨立的 function,讓程式碼更簡潔、更好維護。

什麼是 Composable?

Composable 是 Vue 3 Composition API 的核心應用。它利用 Vue 的響應式系統,例如:ref(), reactive(),將特定的功能邏輯抽離出元件。這不僅提高了程式碼的複用性,也讓單元測試變得更加容易。

它與一般工具函式的差別,在於 它會用到 Vue 的能力

類型會用到響應式與生命週期嗎放在哪裡
Composable會,例如:refcomputedonMountedsrc/composables/
工具函式不會,純輸入輸出,例如:日期格式化src/utils/

常見的 Composable 使用情境

以下是開發中最常被封裝成 Composable 的功能模組:

Composable 名稱功能用途說明
useFetch封裝 API 請求邏輯、處理 Loading 與 Error 狀態
useAuth管理使用者登入狀態、權限檢驗與 Token 存取
useMouse追蹤滑鼠座標位置
useLocalStorage簡化與瀏覽器 localStorage 的同步操作

本系列會實作其中三個:計數器 useCounter滑鼠座標 useMouse非同步請求 useFetch

Composable 的架構設計原則

為了確保專案的整潔與一致性,建議遵循以下開發規範:

命名與目錄規範

  • 目錄命名:統一將邏輯函數放置於 src/composables/ 資料夾下。
  • 函數命名:檔案與函數名稱應以 use 作為開頭,並採用 小駝峰 (camelCase) 命名方式。

use 這個前綴不是語法要求,而是 給人看的提示:看到它就知道這個函式會用到響應式狀態與生命週期,必須在 setup 中呼叫。

設計核心準則

  • 不直接操作 DOM:Composable 應專注於數據與邏輯。若需與 DOM 互動,應透過 ref() 綁定或在生命週期中執行,例如:onMounted()
  • 邏輯與 UI 分離:Composable 只負責 怎麼做 ,而不負責 怎麼長
  • 單一職責原則 (Single Responsibility):每個 Composable 應專注於單一領域,將同一個領域的邏輯聚合在一起。如: 取得多個使用者與單一使用者的資料就可以寫在一起。

專案結構範例

一個標準的 Vue 專案架構應如下所示:

src/
 ├─ composables/
 │   ├─ useFetch.js   # API 請求邏輯
 │   ├─ useMouse.js   # 滑鼠行為追蹤
 │   └─ useAuth.js    # 身分驗證管理
 ├─ App.vue
 └─ main.js

呼叫時機:必須在 setup 中同步呼叫

這是最常見的踩雷點。只要 Composable 內部註冊了 生命週期鉤子watch,Vue 就得知道它屬於哪個元件,因此:

vue
<script setup>
// ✅ 正確:在 setup 中同步呼叫
const { x, y } = useMouse();

// ❌ 失效:Vue 此時已經找不到對應的元件實體
function onClick() {
  const { x, y } = useMouse();
}
</script>

好消息是 生命週期鉤子可以註冊多次,所以一個元件同時使用五個 Composable 也不會互相干擾,各自管好自己的建立與清理。

Composable 與 Pinia 的分工

兩者都能複用邏輯,差別在於 狀態是誰的

ComposablePinia
狀態份數每次呼叫產生一份新的全站共用同一份
適合的資料各元件自己用的,例如:滑鼠座標、表單驗證跨頁面共用的,例如:登入資訊、購物車
需不需要安裝不用,就是一個函式需要安裝並註冊外掛

一句話判斷:資料要不要被別的頁面看到? 不用,就寫成 Composable。

順帶一提:Composable 取代了 mixin

Vue 2 時代靠 mixin 複用邏輯,但它有兩個難以解決的問題:

  • 來源不明:元件裡出現一個變數,卻不知道是哪個 mixin 帶進來的。
  • 名稱衝突:兩個 mixin 都有 loading,後者會默默覆蓋前者。

Composable 用 明確的匯入明確的回傳值 解決了這兩點,解構時還能自由改名,這也是 Vue 3 之後不再推薦 mixin 的原因。

結語:為什麼您該開始使用 Composable?

透過 Composable,我們能將複雜的業務邏輯從 .vue 檔案中解放出來,實現真正的 高內聚、低耦合 。這不僅符合現代前端開發的趨勢,更是從 Vue 菜鳥晉升為資深開發者的必經之路。

常見問題

Composable 就只是一般的函式嗎?

本質上是,差別在於它裡面會使用 Vue 的響應式 API 與生命週期,所以必須在 setup 期間同步呼叫。純粹計算用的工具函式不需要這些能力,放在 utils 就好。

Composable 與 Pinia 該用哪一個?

每次呼叫 Composable 都會產生一份 獨立狀態,適合各元件自己用的邏輯;Pinia 的 store 是 全站共用同一份,適合登入資訊或購物車這類跨頁面資料。

為什麼函式名稱一定要以 use 開頭?

這是社群慣例,用來提示這個函式會使用響應式狀態與生命週期,必須在 setup 中呼叫。一眼就能與普通工具函式區分開來。

Composable 是用來取代 mixin 的嗎?

是。mixin 的問題在於來源不明與屬性名稱衝突,Composable 透過明確的匯入與回傳值解決了這兩點,也能自由重新命名解構出來的變數。

Composable 可以在事件處理函式裡呼叫嗎?

若它內部註冊了 生命週期鉤子watch,就必須在 setup 中同步呼叫,寫在按鈕事件裡會失效。單純回傳資料、沒用到生命週期的函式則不受此限。

延伸閱讀