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 方式の
created、mountedなどは使用しません。 <script setup>内で直接実行されるコードはcreated/beforeCreateに該当します。別途フックは必要ありません。
| Options API | Composition API | 用途 |
|---|---|---|
mounted | onMounted | DOM アクセス、外部ライブラリ初期化 |
unmounted | onUnmounted | イベントリスナー解除、タイマークリア |
updated | onUpdated | DOM 更新後の処理(使用を最小化) |
beforeUnmount | onBeforeUnmount | クリーンアップ処理の開始 |
typescript
import { onMounted, onUnmounted } from 'vue'
onMounted(() => {
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
})