Contents
Vue.js 3 コンポーネントの作り方:実践的な手順とコード例
Vue.js 3で効率的にコンポーネントを作成するには、公式ドキュメントに基づいた理解が不可欠です。この記事では、初心者向けにSingle File Component(SFC)の構造やプロパティ・イベントの使い方を解説し、最終的にシンプルなカウンターコンポーネントを作成して動作確認する手順まで詳しくご案内します。Vue.js 3 コンポーネント 作り方に関する悩みを解決しましょう。
Vue.js 3でコンポーネントを作成する前に知っておくべきこと
Vue.js 3は、コンポーネントベースの開発スタイルが特徴です。このアプローチにより、UIを再利用可能なピースに分割できるため、アプリケーションの保守性と拡張性が向上します。公式ドキュメントでは、「コンポーネントは HTML 要素と同じようにネスト可能で、独自ロジックをカプセル化できる」と述べています。
初心者向けに重要なポイントとして、以下を押さえてください:
- SFC(Single File Component)が標準的な構造
- Composition APIの導入により、関数ベースでの開発が可能
- ネイティブWebコンポーネントとの連携も公式サポート済み
Single File Component(SFC)の基本構造
Vue.js 3では、HTML、JavaScript、CSSを1つのファイルにまとめたSFC(Single File Component)が主流です。この形式により、コンポーネントのロジックとスタイルが同一ファイル内で完結します。
SFCの構成要素比較表
|
1 2 3 4 5 6 7 8 |
| 項目 | 内容 | 補足 | |--------------|--------------------------------|---------------------------------| | **template** | HTML構造を定義 | `<template>`タグで囲む | | **script** | JavaScriptロジック | Vue 3では`<script setup>`が推奨 | | **style** | CSSスタイル | `scoped`属性でスコープ限定 | |
templateセクションの役割
templateセクションは、コンポーネントに描画するHTML構造を定義します。以下に例を示します。
|
1 2 3 4 5 6 7 |
<template> <div class="counter"> <p>{{ count }}</p> <button @click="increment">カウントアップ</button> </div> </template> |
注意:
<script setup>構文はVue 3用に設計された簡潔な記法です。初心者向けには「Composition API(組み合わせAPI)」と呼ばれる新しい開発スタイルが採用されています。
scriptセクションの書き方
scriptセクションでは、コンポーネントのJavaScriptロジックを記述します。Vue 3では<script setup>構文を使用することで、コードが簡潔になります。
|
1 2 3 4 5 6 7 8 9 |
<script setup> import { ref } from 'vue' const count = ref(0) function increment() { count.value++ } </script> |
ポイント:
ref()はリアクティブなデータを管理するための関数です。reactive()を使用すると複合構造(オブジェクト/配列)にも対応可能です。
styleセクションのスコープ設定
styleセクションでは、CSSスタイルを記述できます。scoped属性を追加することで、スタイルがこのコンポーネント内でしか適用されないよう限定されます。
|
1 2 3 4 5 6 7 |
<style scoped> .counter { font-size: 1.5rem; text-align: center; } </style> |
補足: スコープ付きスタイルはコンポーネントごとに独立しており、他のコンポーネントとのスタイル競合を防ぎます。
コンポーネント登録方法(グローバル/ローカル)
Vue.js 3では、コンポーネントをグローバルに登録するか、特定のコンポーネント内でローカルに登録できます。
グローバル登録の実装手順
グローバル登録は Vue.createApp().component() を使用します。これにより、アプリケーション全体で利用可能なコンポーネントを作成できます。
|
1 2 3 4 5 6 7 |
import { createApp } from 'vue' import Counter from './components/Counter.vue' const app = createApp(App) app.component('Counter', Counter) app.mount('#app') |
ローカル登録のベストプラクティス
ローカル登録は、コンポーネント内でのみ利用する場合に適しています。components オプションで定義します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<script setup> import { ref } from 'vue' import Counter from './Counter.vue' const count = ref(0) </script> <template> <div> <Counter /> </div> </template> |
propsとeventsの使い方
コンポーネント間でデータをやり取りするには、props(プロパティ)と events(イベント)を使用します。これらは、Vue.jsの単方向データフローに基づいて動作します。
propsの型定義とデフォルト値設定
propsは親コンポーネントから子コンポーネントに情報を渡すために使用されます。defineProps()関数で型を定義できます。
|
1 2 3 4 5 6 7 8 9 |
<script setup> const props = defineProps({ initialValue: { type: Number, default: 0 } }) </script> |
例: 親コンポーネントから初期値を渡す場合、以下のように記述します。
|
1 2 3 4 |
<template> <Counter :initialValue="5" /> </template> |
emitイベントの定義と発火方法
子コンポーネントが親に値を通知するには、defineEmits()関数でイベントを定義し、発火します。
|
1 2 3 4 5 6 7 8 |
<script setup> const emit = defineEmits(['update']) function increment() { emit('update', count.value + 1) } </script> |
例: 親コンポーネントは
@update="handleUpdate"のようにイベントを受信できます。
Composition APIでの実装例
Composition APIは、Vue.js 3で導入された新しい開発スタイルです。関数ベースの構造により、ロジックの再利用性が高まります。
setup()関数の基本構文
<script setup>構文を使用すると、コードが簡潔になります。
|
1 2 3 4 5 6 7 8 9 |
<script setup> import { ref } from 'vue' const count = ref(0) function increment() { count.value++ } </script> |
refとreactiveの使い分け
ref():単一値をリアクティブに管理する場合に使用reactive():オブジェクトや配列のような複合構造をリアクティブにする場合に使用
|
1 2 3 4 5 6 7 |
<script setup> import { ref, reactive } from 'vue' const count = ref(0) const user = reactive({ name: 'Alice', age: 25 }) </script> |
ライフサイクルフックの利用方法
onMounted()やonUnmounted()などのライフサイクルフックは、コンポーネントがDOMに追加または削除されたタイミングで実行されます。
|
1 2 3 4 5 6 7 8 9 10 |
<script setup> import { ref, onMounted } from 'vue' const count = ref(0) onMounted(() => { console.log('コンポーネントがマウントされました') }) </script> |
ネイティブWebコンポーネントとの連携
Vue.jsは、ネイティブのWebコンポーネントと良好に連携可能です。customElements.define()を使ってカスタム要素を登録できます。
カスタム要素の登録方法
以下のように、HTMLに自作のWebコンポーネントを定義します。
|
1 2 3 4 5 6 7 |
class MyComponent extends HTMLElement { connectedCallback() { this.innerHTML = '<p>これはカスタムコンポーネントです。</p>' } } customElements.define('my-component', MyComponent) |
Vueコンポーネントとネイティブ要素の相互作用
Vueコンポーネント内でネイティブWebコンポーネントを使用する場合、shadow DOMとの併用に注意が必要です。ただし、公式ドキュメントでは「ネイティブコンポーネントは Vue コンポーネントと同様に扱える」とされています。
注意: この記述は公式ドキュメントに基づいたものですが、最新版での確認をお勧めします。
実際にプロジェクトで使ってみましょう
シンプルなカウンターコンポーネントの作成手順
Counter.vueというファイルを作成<template>に表示用のHTMLを記述<script setup>でカウントアップロジックを実装<style scoped>でスタイルを適用
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<template> <div class="counter"> <p>{{ count }}</p> <button @click="increment">カウントアップ</button> </div> </template> <script setup> import { ref } from 'vue' const count = ref(0) function increment() { count.value++ } </script> <style scoped> .counter { font-size: 1.5rem; text-align: center; } </style> |
動作確認とデバッグ方法
プロジェクトにCounter.vueを登録し、親コンポーネントから呼び出してください。以下のようにして動作確認できます。
|
1 2 3 4 5 6 7 8 9 10 |
<template> <div id="app"> <Counter /> </div> </template> <script setup> import Counter from './components/Counter.vue' </script> |
- Vue.js 3のコンポーネント開発は、SFC形式とComposition APIが中心です
- propsやeventsでデータフローを管理し、ローカル・グローバル登録で構成を最適化
- 実際のプロジェクトでは、カウンターのような単純なコンポーネントから試すのがおすすめ
実際にコードを書いてみてください。Vue.js 3は、シンプルかつ強力な開発スタイルを提供しています。