核心修練
Logic ReuseAuto-imports

Composables 與 Utils

在 Nuxt 開發中,我們經常需要提取共用邏輯。Nuxt 提供了兩個主要目錄:composables 與 utils,它們都具備自動引入 (Auto-import) 的特性,但用途卻大不相同。

Composables

composables/ 目錄用於存放有狀態 (Stateful) 的邏輯,通常涉及 Vue 的響應式系統 (Refs, Computed) 或生命週期 Hooks。

最佳實踐

  • 檔案與函數名稱應以 use 開頭 (e.g., useUser.ts)。
  • 優先使用 Named Export 以利重構與測試。
composables/useCounter.ts
// composables/useCounter.ts
export const useCounter = () => {
  const count = ref(0)
  
  const increment = () => {
    count.value++
  }

  return {
    count,
    increment
  }
}

Utils

utils/ 目錄用於存放無狀態 (Stateless) 的輔助函數。這些函數通常是純函數 (Pure Functions),輸入相同則輸出相同,不依賴外部狀態。

utils/format.ts
// utils/format.ts
export const formatDate = (date: Date): string => {
  return new Intl.DateTimeFormat('zh-TW').format(date)
}

export const formatCurrency = (amount: number): string => {
  return new Intl.NumberFormat('zh-TW', { 
    style: 'currency', 
    currency: 'TWD' 
  }).format(amount)
}

兩者差異

特性ComposablesUtils
狀態依賴有狀態 (Refs, Reactive)無狀態 (Pure Functions)
Nuxt Context可使用 (useNuxtApp, useRoute)通常不使用
命名慣例useFeatureverbNoun (e.g. formatDate)

自動引入機制

Nuxt 會自動掃描這兩個目錄,並將導出的函數自動引入到您的頁面與元件中。

巢狀目錄掃描

預設情況下,Nuxt 只會掃描頂層檔案。若要掃描巢狀目錄 (e.g., composables/cart/index.ts),該目錄必須包含 index.ts 重新導出,或者在 nuxt.config.ts 中手動配置。

pages/index.vue
<script setup>
// 無需 import,直接使用!
const { count, increment } = useCounter()
const price = formatCurrency(1000)
</script>