vue3-component-decomposition について
Vue 3 開発向けのスキルで、大きなコンポーネントを読みやすさを保ちながら、小さくテスト可能な単位に分割します。表示、状態、副作用、I/O を分離する手順と、コンポーネントやコンポーザブルの境界を示します。
主な機能
- 01リファクタリング前に責務を整理
- 02表示用の子コンポーネントを抽出
- 03props、emits、slots の契約を明確化
- 04再利用可能な状態ロジックをコンポーザブルへ移動
- 05テンプレートと副作用を管理しやすくする
活用シーン
- 01複数の責務を持つコンポーネントの再構成
- 02複雑または重複したテンプレートの簡素化
- 03再利用可能なリアクティブロジックの分離
- 04コンポーネントのテスト容易性向上
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ noartem/ skills --skill vue3-component-decompositionインストール後、Claude Code で/vue3-component-decompositionを入力して読み込まれたか確認します。
同梱ファイルreferences/decomposition-playbook.md
詳細
Vue 3 コンポーネントの分割
読みやすさを損なわずに、大きな Vue 3 コンポーネントを小さくテスト可能な単位に分割します。
使用する場面
- コンポーネントが複数の関心事(UI の描画、データ取得、フォームロジック、フィルタリング、副作用)を扱っている
setup()または<script setup>の内容が増えて、全体を把握しにくくなっている- テンプレートに複雑な式や繰り返しのブロックが含まれている
- ある機能への変更が、無関係な動作を頻繁に壊している
分割のワークフロー
- コードを移動する前に、責務を整理します。
view(マークアップ/プレゼンテーション)state(refs/reactive/computed)effects(watch/watchEffect/ライフサイクル)io(API 呼び出し)
- まずプレゼンテーション用のサブコンポーネントを抽出します。
- 親と子の間に明示的なインターフェース(
props、emits、slots)を定義します。 - 再利用可能な状態管理ロジックをコンポーザブルに抽出します。
- 親コンポーネントは、データフローと機能の構成を調整する役割を担います。
コンポーネントのベストプラクティス
- 1 ファイルにつき 1 コンポーネントを使用し、複数の単語からなるコンポーネント名を付けます。
- テンプレートの式はシンプルに保ち、複雑な式は computed の値に移します。
v-forには:keyを使用し、同じ要素でv-ifとv-forを組み合わせないでください。- 型付きで明示的な props の契約と、型付きの emits を使用します。
- 可変の UI 領域には、真偽値の props を増やすのではなく
slotsを優先します。 - 子コンポーネントは、1 つの UI 上の関心事に集中させます。
コンポーザブルのベストプラクティス
use接頭辞を付けてコンポーザブルに名前を付けます(useOrdersTable、useUserFilters)。- 分割代入してもリアクティビティが保たれるよう、refs/computed/メソッドをプレーンなオブジェクトとして返します。
- リアクティブな入力(値/ref/getter)を受け取り、
toValue()で正規化します。 - ロジックがリアクティブな入力に依存する場合は、
watchEffect()内でtoValue()を呼び出します(または refs/getters を直接監視します)。 - DOM の副作用は
onMounted()で実行し、必ずonUnmounted()でクリーンアップします。 - 意図的に共有状態を構築する場合を除き、隠れたグローバル可変状態は避けます。
推奨する構成
src/
components/
feature/
OrdersPage.vue # orchestrator
OrdersToolbar.vue # presentational controls
OrdersTable.vue # table rendering
OrdersTableRow.vue # row rendering
composables/
useOrdersQuery.ts # fetch/pagination/sort
useOrdersFilters.ts # filter state and derived query
useOrdersSelection.ts # row selection logic
守るべき指針
- 独立した価値のない小さなラッパーは抽出しないでください。
- 「何でもこなすコンポーザブル」は作らず、ビジネス上の機能ごとに分割します。
- 親の状態全体を子に渡さず、必要な props だけを渡します。
- プレゼンテーション用コンポーネントにビジネスロジックを混在させないでください。
PR チェックリスト
- 親コンポーネントが実装の羅列ではなく、機能を調整するものとして読める
- 子コンポーネントの API が明確で、単独で動作を把握できる
- コンポーザブルの責務が明確で、予測しやすい戻り値の形になっている
- 副作用がクリーンアップされ、SSR に安全である
- テンプレートの複雑さが軽減され、より小さな単位を対象にテストできる
参考資料
- Vue ドキュメント:コンポーザブル - https://vuejs.org/guide/reusability/composables.html
- Vue スタイルガイド(古いものですが、今でも参考になります):
コメント
Markdown 対応