components について
Vue アプリを開発する人向けに、UI の構成や再利用可能な要素の組み立て方を解説するスキルです。単一ファイルコンポーネント、親子間の連携、リアクティブな状態管理を扱います。
主な機能
- 01Vue コンポーネントの構造
- 02単一ファイルコンポーネントの構成
- 03親子間の props とイベント
- 04ref() と reactive() による状態管理
- 05再利用可能な UI コンポーネントの抽出
活用シーン
- 01Vue アプリの UI 構造の設計
- 02複雑なビューの子コンポーネントへの分割
- 03繰り返し使う UI 要素の再利用
- 04リアクティブなインタラクティブコンポーネントの構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ patternsdev/ skills --skill componentsインストール後、Claude Code で/componentsを入力して読み込まれたか確認します。
詳細
コンポーネント
目次
Vue コンポーネントは、マークアップ(HTML)、ロジック(JS)、スタイル(CSS)をまとめることで、Vue アプリの構成要素となります。
Vue アプリケーションで作業する際は、UI に表示されるほぼすべての要素が、多くの場合 Vue コンポーネントの一部であることを理解することが重要です。これは、Vue アプリケーションがコンポーネントの中にコンポーネントをネストした階層構造で構成されていることが多いためです。
使う場面
- あらゆる Vue アプリケーションを構築するための基礎知識として活用します
- Vue で UI 要素を構造化、組み合わせ、再利用する方法を理解するのに役立ちます
手順
<template>、<script setup>、<style>セクションを含む単一ファイルコンポーネント(.vueファイル)を使用します- 大きなコンポーネントの再利用可能な部分を、小さな子コンポーネントに切り出します
- リアクティブなプリミティブ値には
ref()を、リアクティブなオブジェクトにはreactive()を使用します - props を使って親から子へデータを渡し、子から親へはイベントを発行します
詳細
適切に構造化されたコンポーネントでアプリケーションを構築することが特に重要である主な理由のひとつは、再利用性と保守性です。
コンポーネントへの理解を深めるため、実際にコンポーネントを作成してみましょう。ビルドプロセス(Webpack など)を含まないアプリケーションで Vue コンポーネントを作成する最も簡単な方法は、Vue 固有のオプションを含むプレーンな JavaScript オブジェクトを作成することです。
export default {
props: ["name"],
template: `<h1>Hello, my name is {{ name }}</h1>`,
};
このコンポーネントには props プロパティが定義されており、name という名前の prop をひとつ受け取ります。props を使うと、親コンポーネントからコンポーネントへデータを渡せます。
template プロパティは、コンポーネントの HTML テンプレートを定義します。この例では、"Hello, my name is" というテキストの後に name prop の値を表示する <h1> 見出しタグが含まれています。値は Vue の二重波括弧構文 {{ }} を使ってレンダリングされます。
コンポーネントをプレーンな JavaScript オブジェクトとして定義する方法のほかに、Vue でコンポーネントを作成する最も一般的な方法は、単一ファイルコンポーネント(SFC)を使うことです。単一ファイルコンポーネントとは、以下に示すように、特別な .vue ファイル内でコンポーネントの HTML、CSS、JS をすべて定義できるコンポーネントです。
<template>
<h1>Hello, my name is {{ name }}</h1>
</template>
<script setup>
const { name } = defineProps(["name"]);
</script>
注:Vue の単一ファイルコンポーネントは、Vite などのビルドツールによって実現されています。これらのツールは
.vueコンポーネントを、ブラウザーで扱えるプレーンな JavaScript モジュールにコンパイルします。
コンポーネント=構成要素
コンポーネントをより小さなコンポーネントに分割する方法を示すため、簡単な例を見ていきましょう。架空の Tweet コンポーネントを考えてみます。
このコンポーネントは、次のように実装できます。
<template>
<div class="Tweet">
<image class="Tweet-image" :src="image.imageUrl" :alt="image.description" />
<div class="User">
<image class="Avatar" :src="author.avatarUrl" :alt="author.name" />
<div class="User-name">{{ author.name }}</div>
</div>
<div class="Details">
<div class="Tweet-text">{{ text }}</div>
<div class="Tweet-date">{{ formatDate(date) }}</div>
</div>
</div>
</template>
<script setup>
// ...
</script>
上記のコンポーネントは構造が密集しているため、操作が難しく、個々の部分を再利用するのも難しいと考えられます。より組み合わせやすくするために、このコンポーネントからいくつかのコンポーネントを切り出せます。
メインの Tweet コンポーネントを、TweetUser コンポーネントと TweetDetails コンポーネントの親にできます。TweetUser はユーザー情報を表示し、ユーザーのアバターを表示する TweetAvatar コンポーネントの親になります。TweetDetails は、ツイートのテキストや投稿日時など、ツイートの追加情報を表示します。
まず、アバター画像の要素を含む子コンポーネント TweetAvatar を作成します。
<template>
<image class="Avatar" :src="author.avatarUrl" :alt="author.name" />
</template>
<script setup>
// ...
</script>
次に、TweetAvatar コンポーネントと関連するユーザー情報をレンダリングする TweetUser コンポーネントを作成します。
<template>
<div class="User">
<TweetAvatar />
<div class="User-name">{{ author.name }}</div>
</div>
</template>
<script setup>
import { TweetAvatar } from "./TweetAvatar.vue";
</script>
続いて、ツイートの残りの情報をレンダリングする TweetDetails コンポーネントを作成します。
<template>
<div class="Details">
<div class="Tweet-text">{{ text }}</div>
<div class="Tweet-date">{{ formatDate(date) }}</div>
</div>
</template>
<script setup>
// ...
</script>
最後に、新しく作成した子コンポーネントを使って、親の Tweet コンポーネントのテンプレートを簡潔にできます。
<template>
<div class="Tweet">
<image class="Tweet-image" :src="image.imageUrl" :alt="image.description" />
<TweetUser :author="author" />
<TweetDetails :text="text" :date="date" />
</div>
</template>
<script setup>
// ...
</script>
コンポーネントの切り出しは面倒に思えるかもしれませんが、再利用可能なコンポーネントがあると、大規模なアプリのコーディングが簡単になります。コンポーネントを簡潔にする際の判断基準として、UI の一部が何度も使われている(Button、Panel、Avatar など)、あるいはそれ自体が十分に複雑である(App、FeedStory、Comment など)場合は、独立したコンポーネントとして切り出す候補になります。
リアクティブな状態
リアクティブな状態は Vue コンポーネントの基本的な概念であり、動的で応答性の高いユーザーインターフェイスを実現します。コンポーネントがデータの変更を自動的に反映して更新できるようになります。
Vue では、ref() 関数(単独のプリミティブ値の場合)や reactive() 関数(オブジェクトの場合)を使って、リアクティブなデータプロパティを定義できます。カウンターコンポーネントの簡単な例を見てみましょう。
<template>
<div>
<h2>Counter: {{ count }}</h2>
<button @click="increment">Increment</button>
<button @click="decrement">Decrement</button>
</div>
</template>
<script setup>
import { ref } from "vue";
const count = ref(0);
const increment = () => {
count.value++;
};
const decrement = () => {
count.value--;
};
</script>
上記の例では、リアクティブなプロパティ count を定義し、値を 0 に初期化しています。テンプレートでは二重波括弧 {{ }} を使って、count の現在の値を表示します。
テンプレートには "Increment" と "Decrement" の 2 つのボタンもあり、@click ディレクティブを使って、それぞれ対応する increment() メソッドと decrement() メソッドにバインドされています。これらのメソッド内では、リアクティブなプロパティ count の値にアクセスして変更します。Vue は変更を検出し、新しい値が反映されるようにコンポーネントのレンダリングを自動的に更新します。
Vue コンポーネントのリアクティブな状態を使うと、データの変更をシームレスに管理、追跡できるため、インタラクティブで動的なユーザーインターフェイスを簡単に構築できます。
まとめ
この記事では、コンポーネントの概念を簡単に紹介しました。他の記事やガイドでは、Vue と Vue コンポーネントを扱ううえでよく使われる重要なパターンについて、さらに詳しく解説します。内容には次の項目などが含まれます。
<script setup>構文の使用- ステートフルなロジックを再利用するためのコンポーザブルの作成
- provide/inject を使った複数のコンポーネントへのデータの受け渡し
- アプリケーション全体の状態管理について
- 動的コンポーネントを使ったコンポーネントの動的な切り替え
- JSX を使ったコンポーネントテンプレートのレンダリング
- そのほかにも多数あります。