※ 当ブログ「日々是事始め(コレコト)」はプロモーションを含みます。
コンポーネントを作り込んでいくと、.vue の <script setup> にデータ取得・ローディング管理・エラー処理…とロジックが溜まっていき、画面が読みにくくなります。しかも同じような処理を別の画面でもう一度書くはめに。この「ロジックの置き場所」と「再利用」を解決するのが composables(コンポーザブル)です。この記事で考え方を整理します。
※ 学習用に調べた内容を個人的にまとめたものです。文章は AI の補助を受けて作成しています。
composable=リアクティブなロジックをまとめた関数
composable は、ref や computed などのリアクティブな状態と処理を1つにまとめた再利用できる関数です。慣習として名前を use〜 で始めます(useTasks、useLoading など)。.vue から呼び出して、状態と操作を受け取って使います。
// src/features/counter/composables/useCounter.ts
import { ref } from 'vue'
export function useCounter() {
const count = ref(0)
const increment = () => count.value++
const reset = () => (count.value = 0)
return { count, increment, reset }
}
<!-- 画面から使う -->
<script setup lang="ts">
import { useCounter } from '@/features/counter/composables/useCounter'
const { count, increment, reset } = useCounter()
</script>
<template>
<p>{{ count }}</p>
<button @click="increment">+1</button>
<button @click="reset">リセット</button>
</template>
ロジックが useCounter.ts に移り、.vue は「呼んで表示するだけ」に。別の画面でも useCounter() を呼べば同じロジックを使い回せます。
.vue を薄く保つ
実務では、API 呼び出しやローディング・エラー管理を composable に逃がすと、画面がぐっと読みやすくなります。役割で層を分けるイメージです。
TaskListPage.vue … 表示する(薄い)
↓ 呼ぶ
useTasks.ts … 一覧の取得・状態・エラー管理(composable)
↓ 呼ぶ
taskRepository.ts … 実際のAPI通信をまとめた層
この「画面 → composable → API層」という一方向の流れは、後半の REST API 連携編でそのまま使います。画面に通信コードを直書きしないための土台になります。
Pinia との違い
「composable と Pinia、どちらを使う?」は最初に迷うところ。役割が違います。
| composable | Pinia | |
|---|---|---|
| 役割 | ロジックの再利用単位 | 状態の共有置き場 |
| 状態の扱い | 呼ぶたびに新しく作られる(基本) | アプリ全体で1つを共有 |
| 向く用途 | 「一覧取得」「入力フォーム」などの処理のまとまり | ログイン情報・カートなど画面をまたぐ共有 |
ざっくり「処理をまとめて使い回したい → composable」「画面をまたいで同じデータを共有したい → Pinia」。両者は対立せず、composable の中から Pinia を使うこともよくあります。
もっと体系的に学ぶなら(書籍)
この記事はシリーズの一部です。TypeScript前提で Composition API・Pinia・Vue Router・テストまで一冊で体系的に学びたい方には、内容がそのまま重なる次の本がおすすめです。
PR
📕 紙の本
Vue 3 フロントエンド開発の教科書 [ WINGSプロジェクト 齊藤 新三 ] 価格:3960円 |
📱 電子書籍版
Vue 3 フロントエンド開発の教科書 【電子書籍】[ WINGSプロジェクト 齊藤新三【著】 ] 価格:3960円 |
次に読む



