Vue 3 の Composition API では、処理の共通化や再利用性を高める手段として Composable関数 が広く使われています。ロジックを切り出すことで、コンポーネントの可読性を高め、メンテナンス性を向上させることができます。
この記事では、代表的な共通ロジックである「API取得処理」と「フォームバリデーション処理」を対象に、useFetch
とuseForm
という2つのComposable関数を実装し、活用方法を解説します。
Composable関数とは
Composable関数とは、Vue 3 の Composition API を使って定義する「状態とロジックの再利用可能なユニット」です。通常、ref
や reactive
、watch
、computed
などを内部で利用し、必要なデータや関数を返します。
命名には use〜
というプレフィックスを用いるのが一般的です(例:useUser
、useFetch
など)。
useFetchの実装例|API取得ロジックの共通化
// composables/useFetch.js
import { ref } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(false);
const fetchData = async () => {
loading.value = true;
error.value = null;
try {
const res = await fetch(url);
if (!res.ok) throw new Error('Fetch failed');
data.value = await res.json();
} catch (err) {
error.value = err.message;
} finally {
loading.value = false;
}
};
return {
data,
error,
loading,
fetchData
};
}
このuseFetch
を使えば、APIからのデータ取得をシンプルに扱うことができます。
使用例
<script setup>
import { onMounted } from 'vue';
import { useFetch } from './composables/useFetch';
const { data, error, loading, fetchData } = useFetch('https://api.example.com/users');
onMounted(() => {
fetchData();
});
</script>
<template>
<div v-if="loading">読み込み中...</div>
<div v-else-if="error">エラー: {{ error }}</div>
<ul v-else>
<li v-for="user in data" :key="user.id">{{ user.name }}</li>
</ul>
</template>
useFormの実装例|フォームバリデーションの共通化
// composables/useForm.js
import { reactive, computed } from 'vue';
export function useForm(initialState = {}) {
const form = reactive({ ...initialState });
const errors = reactive({});
const validate = () => {
errors.name = !form.name ? '名前は必須です' : '';
errors.email = !form.email ? 'メールアドレスは必須です' : '';
return Object.values(errors).every(e => !e);
};
const isValid = computed(() => Object.values(errors).every(e => !e));
return {
form,
errors,
validate,
isValid
};
}
使用例
<script setup>
import { useForm } from './composables/useForm';
const { form, errors, validate, isValid } = useForm({
name: '',
email: ''
});
const submit = () => {
if (validate()) {
alert('送信成功');
}
};
</script>
<template>
<form @submit.prevent="submit">
<div>
<input v-model="form.name" placeholder="名前">
<p v-if="errors.name">{{ errors.name }}</p>
</div>
<div>
<input v-model="form.email" placeholder="メールアドレス">
<p v-if="errors.email">{{ errors.email }}</p>
</div>
<button :disabled="!isValid">送信</button>
</form>
</template>
まとめ
Composable関数は、Vueコンポーネントのロジックを整理・共通化する強力な手段です。useFetch
でAPI呼び出しの共通処理を、useForm
でバリデーション処理を切り出すことで、コンポーネントをよりシンプルに保つことができます。
アプリケーションの拡張性やチーム開発での可読性を高めるためにも、プロジェクト内で積極的にComposable関数を導入してみてください。