Skip to content

Composition API 基本規則

10.1.1. 基本原則

  • <script setup> を必須で使用します。 Options API は使用しません。
  • TypeScript を必須で使用します。.vue ファイルの <script> タグには必ず lang="ts" を明示します。
  • SFC(Single File Component) 内のブロック順序は <script><template><style> の順序に従います。
vue
<script setup lang="ts">
import { ref, computed } from 'vue'

const count = ref(0)
const doubled = computed(() => count.value * 2)
</script>

<template>
  <div>
    <p>{{ doubled }}</p>
    <button @click="count++">増加</button>
  </div>
</template>

<style scoped>
/* スタイル */
</style>

10.1.2. Composable 作成規則

  • Composable 関数名は use プレフィックスで始めます。
  • ファイルの配置場所は src/composables/ ディレクトリとします。
  • 1つのファイルに1つの composable を定義します。
typescript
// src/composables/useUser.ts
import { ref } from 'vue'
import { fetchUser } from '@/api/user'
import type { User } from '@/types/user'

export function useUser(userId: string) {
  const user = ref<User | null>(null)
  const loading = ref(false)
  const error = ref<Error | null>(null)

  async function load() {
    loading.value = true
    try {
      user.value = await fetchUser(userId)
    } catch (e) {
      error.value = e as Error
    } finally {
      loading.value = false
    }
  }

  return { user, loading, error, load }
}

10.1.3. ref と reactive の使用規則

  • 基本型(string, number, boolean)には ref を使用します。
  • オブジェクト/配列型にも ref を基本として使用します。reactive は深いネストオブジェクトでリアクティビティ追跡が必要な場合にのみ限定的に使用します。
  • ref 値にアクセスする際は .value を明示します。テンプレートでは自動アンラップされます。
typescript
// 正しい例
const name = ref<string>('')
const items = ref<Item[]>([])
const form = ref<FormData>({ name: '', email: '' })

// 限定的に許容 — reactive 使用
const state = reactive<FormState>({
  fields: { name: '', email: '' },
  errors: {},
  isSubmitting: false,
})

10.1.4. ライフサイクルフック

  • Composition API ライフサイクルフックを使用します。Options API 方式の createdmounted などは使用しません。
  • <script setup> 内で直接実行されるコードは created/beforeCreate に該当します。別途フックは必要ありません。
Options APIComposition API用途
mountedonMountedDOM アクセス、外部ライブラリ初期化
unmountedonUnmountedイベントリスナー解除、タイマークリア
updatedonUpdatedDOM 更新後の処理(使用を最小化)
beforeUnmountonBeforeUnmountクリーンアップ処理の開始
typescript
import { onMounted, onUnmounted } from 'vue'

onMounted(() => {
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})

TIENIPIA QUALIFIED STANDARD