はい、承知いたしました。Vue.js初心者向けの、約5000語を目標とした詳細な入門記事を作成します。
Vue.jsとは? 初心者向けに基本を紹介【入門】
はじめに:なぜVue.jsを学ぶのか?
「Vue.js(ヴュー・ジェイエス)」、最近よく耳にするけど、一体何ができるの? JavaScriptってただでさえ難しいのに、また新しいものを覚えるの?
もしあなたがそう感じているなら、安心してください。Vue.jsは、ウェブサイトやウェブアプリケーションのユーザーインターフェース(UI)を作るためのJavaScriptフレームワークです。フレームワークと聞くと難しそうですが、簡単に言えば「アプリ開発を効率的に、かつ、分かりやすく進めるための、あらかじめ用意された便利な道具やルール」のことです。
現代のウェブ開発の課題
少し前まで、ウェブサイトは主にHTMLで構造を作り、CSSで見た目を整え、JavaScriptはちょっとした動き(例えば、ボタンをクリックしたら何か表示する、フォームの入力チェックをするなど)を加えるために使われるのが一般的でした。
しかし、FacebookやTwitterのような、まるでデスクトップアプリケーションのように動くウェブサイト(これをシングルページアプリケーション – SPAと呼びます)が一般的になるにつれて、ウェブ開発はどんどん複雑になっています。
- データの表示と更新: サーバーから取得したデータを画面に表示し、ユーザーの操作や新しいデータに応じて画面をリアルタイムに更新する必要があります。生のJavaScriptでこれをやろうとすると、コードがすぐに複雑になり、管理が難しくなります。
- インタラクティブな要素: ポップアップ、モーダルウィンドウ、タブ切り替え、ドラッグ&ドロップなど、ユーザーが触れる多くのインタラクティブな要素が必要です。これらの状態管理(開いているか閉じているか、選択されているかなど)を手動で行うのは大変です。
- コードの再利用: 同じような見た目や機能を持つ部分(ボタン、リストアイテム、カード表示など)がウェブサイトのあちこちに登場します。これらを効率的に作り、使い回したい。
- チーム開発: 複数人で開発する場合、コードの書き方や構成に一定のルールがないと、互いのコードを理解しにくくなります。
Vue.jsが解決すること
Vue.jsは、まさにこれらの課題を解決するために登場しました。Vue.jsを使うと、以下のようなメリットがあります。
- データの画面への反映が簡単(リアクティビティ): JavaScriptのデータを変更すると、自動的に画面表示も更新されます。手動でHTML要素を探して書き換える必要がなくなります。これを「リアクティビティ(反応性)」と呼びます。
- UIを「コンポーネント」に分割できる: ウェブサイトを、独立した部品(コンポーネント)の集まりとして考えることができます。例えば、「ヘッダー」「サイドバー」「商品リスト」「ボタン」など、それぞれを一つの部品として作成し、それらを組み合わせてページ全体を構築します。これにより、コードが整理され、再利用しやすくなります。
- 学習コストが比較的低い: ReactやAngularといった他の主要なJavaScriptフレームワークと比較して、Vue.jsは比較的シンプルで理解しやすいと言われています。特にHTML, CSS, JavaScriptの基本的な知識があれば、スムーズに入門できます。
- 柔軟性が高い: 小さな機能追加から大規模なSPAまで、様々な規模のプロジェクトに適用できます。既存のウェブサイトの一部だけにVue.jsを導入することも可能です。
Vue.jsは、シンプルさと強力な機能を兼ね備えており、世界中の多くの開発者に愛されています。特に、日本の開発者の間でも非常に人気が高いフレームワークです。
この入門記事では、Vue.jsの基本的な概念と使い方を、なるべく専門用語を使わずに、多くのコード例とともに解説していきます。この記事を読めば、Vue.jsを使って簡単なUIを作成できるようになり、さらに学習を進めるための土台を築けるはずです。
さあ、Vue.jsの世界へ一歩踏み出しましょう!
Vue.jsを始める準備
Vue.jsを始めるには、いくつかの方法があります。初心者にとって最も手軽なのは、CDN(Contents Delivery Network)を使ってHTMLファイルに直接Vue.jsを読み込む方法です。慣れてきたら、本格的な開発環境を構築するためのCLI(Command Line Interface)を使う方法に移行するのが一般的です。
ここでは、まずCDNを使う方法でVue.jsの基本的な書き方を見ていきましょう。CLIを使った環境構築についても、後ほど簡単に触れます。
必要なもの
Vue.jsの基本的な学習には、特別なツールはほとんど必要ありません。
- テキストエディタ: HTML, CSS, JavaScriptのコードを書くためのエディタです。Visual Studio Code (VS Code) や Sublime Text、Atomなどが人気です。
- ウェブブラウザ: Chrome, Firefox, Safariなど、現代的なブラウザが必要です。開発者ツール(特にJavaScriptコンソール)をよく使います。
これらが準備できたら、早速Vue.jsを使ってみましょう。
CDNを使ってVue.jsを読み込む
最も簡単な方法は、HTMLファイルの<head>
タグ内、または</body>
タグの直前で、Vue.jsのJavaScriptファイルをインターネット上から読み込むことです。
“`html
“`
ポイント:
<div id="app">
という要素があります。これが、これからVue.jsが「担当する」領域になります。Vue.jsは、指定された要素の中だけを制御し、それ以外の部分は通常のHTMLとして扱われます。<script src="...">
の部分で、Vue.jsの本体であるライブラリを読み込んでいます。https://unpkg.com/vue@3/dist/vue.global.js
は、Vue.jsのバージョン3のファイルを読み込むURLです。このバージョンは開発用で、エラーメッセージなどが親切に表示されます。本番環境ではより軽量なファイルを使います。- 読み込んだVue.jsの後に、自分のJavaScriptコードを書くための
<script>
タグを用意しています。
このHTMLファイルを作成し、ブラウザで開いてみてください。まだJavaScriptコードを書いていないので、画面には {{ message }}
という文字列がそのまま表示されているはずです。
次に、この {{ message }}
の部分を、JavaScriptで定義したデータで置き換えるようにしてみましょう。
Vue.jsの基本:Vueアプリケーションの作成
Vue.jsを使って画面を制御するには、まず「Vueアプリケーション」を作成し、それをHTMLの特定の要素に紐付けます。
先ほどのHTMLファイルの <script>
タグ内に、以下のJavaScriptコードを追加してください。
“`html
“`
このファイルを保存してブラウザで開き直してみてください。今度は {{ message }}
ではなく、「こんにちは、Vue.js!」という文字列が表示されているはずです。
これが、Vue.jsを使った最も基本的な画面表示の仕組みです。
コードの解説
const app = Vue.createApp({...});
Vue.createApp()
という関数を使って、新しいVueアプリケーションの「インスタンス」を作成しています。インスタンスとは、「設計図(クラス)」から実際に作られた「実体」のことだと考えてください。{...}
の部分には、そのアプリケーションが持つ「データ」「機能(メソッド)」「計算プロパティ」などの様々な設定を記述します。これらを「オプション」と呼びます。Vue 3ではcreateApp
にオプションオブジェクトを渡しますが、Vue 2ではnew Vue({...})
という書き方でした。内容は似ています。
data() { return { ... } }
- これは「データオプション」です。Vueインスタンスが管理するデータを定義します。
data
は関数として定義する必要があります(コンポーネントの場合。ルートインスタンスの場合はオブジェクトでも書けますが、関数が推奨されます)。この関数が返すオブジェクトのプロパティ(例:message
)が、Vueインスタンスのデータとして利用可能になります。- ここで定義したデータは、Vue.jsのリアクティビティシステムによって監視されます。データの値が変更されると、それを使用している画面の要素が自動的に更新されます。
app.mount('#app');
- 作成したVueアプリケーションインスタンスを、HTMLの特定の要素に紐付ける処理です。
mount()
メソッドの引数に、CSSセレクタ(ここでは#app
)を指定することで、そのセレクタに合致する最初の要素をVueアプリケーションの「マウント先」とします。- これにより、Vueインスタンスは
#app
要素とその子孫要素の表示を制御するようになります。
{{ }}
とは?(テキスト補間)
{{ message }}
の部分は、Vue.jsのテンプレート構文です。これは「マスタッシュ構文」とも呼ばれます。
{{ }}
の中にJavaScriptの式(ここでは message
というデータ名)を書くと、Vue.jsはその式を評価し、結果をテキストとしてその場所に表示します。
これが、JavaScriptのデータ (message: 'こんにちは、Vue.js!'
) をHTMLの画面 ({{ message }}
) に表示する仕組みです。そして、もしJavaScript側で message
の値が変われば、画面表示も自動的に「こんにちは、Vue.js!」から新しい値に更新されます。これがリアクティビティの基本です。
テンプレート構文とデータバインディング
Vue.jsの強力な機能の一つは、JavaScriptのデータとHTMLの構造を柔軟に連携させる「データバインディング」です。テンプレート構文はこのデータバインディングを行うための記述方法です。
先ほどの {{ }}
はテキストをバインディングする例でしたが、Vue.jsでは要素の属性やイベントなどもデータと紐付けることができます。
ディレクティブとは?
Vue.jsのテンプレート構文でよく使われるのが「ディレクティブ」です。ディレクティブは v-
というプレフィックス(接頭辞)から始まる特別な属性です。要素に特別な振る舞いをさせることができます。
例: v-bind
, v-model
, v-if
, v-for
, v-on
など。
これらのディレクティブを使って、データと画面表示を様々な形で紐付けます。
v-bind
: 属性のバインディング
HTML要素の属性(id
, class
, src
, href
, title
など)の値を、JavaScriptのデータに紐付けたい場合に v-bind
を使います。
“`html
“`
解説:
<a v-bind:href="linkUrl">
v-bind:
の後に属性名 (href
) を指定します。- 属性の値として、JavaScriptのデータ名 (
linkUrl
) を指定します。 - これにより、
<a>
タグのhref
属性の値が、data
オブジェクトのlinkUrl
の値 (https://www.google.com
) になります。
<div v-bind:class="{ active: isActive }">
class
属性をバインディングする場合、JavaScriptのオブジェクト{ className: booleanValue }
を指定すると、booleanValue
がtrue
の場合にclassName
というクラスが要素に追加されます。false
なら追加されません。- この例では、
isActive
がtrue
なので、このdiv
にはactive
クラスが追加されます。
<div v-bind:style="{ color: textColor, fontSize: fontSize + 'px' }">
style
属性も同様に、JavaScriptのオブジェクトでCSSプロパティを指定できます。CSSプロパティ名はキャメルケース(fontSize
)またはケバブケース('font-size'
)で記述できます。- 値にはJavaScriptのデータや式を指定できます。単位が必要な場合は文字列として連結します (
fontSize + 'px'
)。
v-bind
の省略記法:
v-bind:
は :
に省略できます。これがよく使われる記法です。
“`html
省略記法
“`
v-model
: フォーム入力要素の双方向バインディング
v-model
ディレクティブは、<input>
, <textarea>
, <select>
などのフォーム入力要素で特に役立ちます。入力要素の value
とJavaScriptのデータを双方向でバインディングします。
つまり、
- JavaScriptのデータを変更すると、入力要素の表示(入力されている値)も変わる。
- ユーザーが入力要素の値を変更すると、JavaScriptのデータも自動的に更新される。
この「双方向」がポイントです。
“`html
入力されたテキスト: {{ inputText }}
チェックボックスの状態: {{ isChecked }}
チェックしてください
選択されたオプション: {{ selectedOption }}
“`
解説:
<input type="text" v-model="inputText">
inputText
というデータとこのテキスト入力フィールドの値が双方向で紐付けられます。- 初期状態では
inputText
は空文字列なので、入力フィールドは空です。 - ユーザーが入力フィールドに「Hello」と入力すると、
inputText
の値も自動的に"Hello"
に更新されます。 - 逆に、もしJavaScriptコードで
inputText = 'ワールド';
と変更すると、入力フィールドの値も「ワールド」に更新されます。
<input type="checkbox" v-model="isChecked">
- チェックボックスの場合、
v-model
はtrue
/false
の真偽値と紐付けられます。 isChecked
がtrue
ならチェックボックスはチェックされ、false
ならチェックされません。- ユーザーがチェックボックスを操作すると、
isChecked
の値が自動的にtrue
/false
に更新されます。
- チェックボックスの場合、
<select v-model="selectedOption">
select
要素の場合、v-model
は選択されている<option>
のvalue
またはテキストコンテンツと紐付けられます。- 初期状態では
selectedOption
が空文字列なので、<option disabled value="">選択してください</option>
が選択されます(value
が空文字列だからです)。 - ユーザーが「B」を選択すると、
selectedOption
の値が自動的に"B"
に更新されます。
v-model
は、フォームの入力値を扱うタスクを非常にシンプルにしてくれます。
v-on
: イベント処理
ボタンクリックや入力値変更など、ユーザーの操作や発生したイベントに応じてJavaScriptのメソッドを実行したい場合に v-on
ディレクティブを使います。
“`html
カウント: {{ counter }}
名前を入力:
{{ greetingMessage }}
“`
解説:
methods: { ... }
- これは「メソッドオプション」です。Vueインスタンス内で使用する関数を定義します。
- ここで定義した関数は、テンプレート内や他のメソッド内から呼び出すことができます。
- メソッド内から
data
オプションで定義したデータにアクセスするには、this.データ名
のようにthis
を使います。
<button v-on:click="increment">
v-on:
の後にイベント名 (click
) を指定します。- 属性の値として、実行したいメソッド名 (
increment
) を指定します。 - このボタンがクリックされると、Vueインスタンスの
methods
オプションで定義されたincrement
関数が実行されます。
<button v-on:click="greet">
- このボタンがクリックされると、
greet
関数が実行されます。 greet
関数はthis.name
(v-model
でテキスト入力と紐付けられているデータ)の値を使ってthis.greetingMessage
を更新しています。greetingMessage
は画面に表示されているため、画面も自動的に更新されます。
- このボタンがクリックされると、
v-on
の省略記法:
v-on:
は @
に省略できます。これもよく使われる記法です。
html
<button @click="increment">省略記法</button>
イベント修飾子:
v-on
には、イベントの挙動を簡単に制御するための「イベント修飾子」という便利な機能があります。.
を使ってイベント名に追加します。
例:
.prevent
: イベントのデフォルトの動作をキャンセル(event.preventDefault()
と同じ)- フォーム送信時にページ遷移を防ぐ場合など:
<form @submit.prevent="handleSubmit">
- フォーム送信時にページ遷移を防ぐ場合など:
.stop
: イベントの伝播(親要素へのイベント伝達)を停止(event.stopPropagation()
と同じ)- 子要素のクリックイベントが親要素に伝わらないようにする場合など:
<div @click="doSomething"><button @click.stop="doSomethingElse"></button></div>
- 子要素のクリックイベントが親要素に伝わらないようにする場合など:
.once
: イベントリスナーを一度だけ実行.capture
: キャプチャフェーズでイベントを発生させる.self
: イベントが要素自身によって発生した場合のみ実行
“`html
“`
v-if
, v-else-if
, v-else
: 条件付きレンダリング
特定の条件に基づいて要素を表示したり非表示にしたりしたい場合に v-if
, v-else-if
, v-else
ディレクティブを使います。
v-if
は、指定された式が true
の場合に要素をレンダリング(DOMに追加)します。false
の場合は要素が完全に削除されます。
“`html
このテキストは表示/非表示が切り替わります。
= 50″>頑張りました!
もう少し頑張りましょう。
“`
解説:
<p v-if="isShow">
isShow
の値がtrue
の場合、この<p>
要素がHTMLに追加されて画面に表示されます。isShow
の値がfalse
になると、この<p>
要素はDOMから完全に削除され、画面には表示されなくなります。
v-else-if="score >= 50"
,v-else
- これらのディレクティブは、直前の
v-if
またはv-else-if
と組み合わせて使います。 v-if
の条件が満たされず、かつv-else-if
の条件が満たされた場合にその要素が表示されます。- いずれの条件も満たされない場合に
v-else
の要素が表示されます。
- これらのディレクティブは、直前の
注意点: v-if
, v-else-if
, v-else
は、必ず隣接する要素に記述する必要があります。途中に他の要素があると正しく機能しません。
v-show
: 条件付き表示
v-show
も条件に基づいて要素を表示/非表示するディレクティブですが、v-if
とは仕組みが異なります。
v-show
は、条件が false
の場合でも要素をDOMから削除しません。代わりに、CSSの display: none;
スタイルを適用して見た目上非表示にします。条件が true
になると、そのスタイルを解除します。
“`html
このテキストは v-show で表示/非表示が切り替わります。
“`
v-if
と v-show
の使い分け:
v-if
: 条件の切り替えが頻繁ではない場合。要素の作成・破棄のコストはかかりますが、非表示時はDOMに存在しないため初期レンダリングコストは低いです。v-show
: 条件の切り替えが頻繁に行われる場合。初期レンダリング時に要素は常にDOMに存在するため初期コストはかかりますが、表示/非表示はCSSの切り替えだけなので高速です。
要素が DOM に存在するかどうかが重要か(例: 子コンポーネントのライフサイクル)、あるいは頻繁な切り替えパフォーマンスが重要か、で選びます。
v-for
: リストレンダリング
配列やオブジェクトのデータに基づいて、同じ要素を繰り返し表示したい場合に v-for
ディレクティブを使います。
“`html
果物リスト
- {{ item }}
ユーザーリスト
- {{ index + 1 }}: {{ user.name }} ({{ user.age }}歳)
オブジェクトのプロパティを繰り返し表示
- {{ index }}. {{ key }}: {{ value }}
“`
解説:
<li v-for="item in fruits">
v-for="変数名 in 配列またはオブジェクト"
という形式で記述します。- この例では、
fruits
配列の各要素が順番にitem
という変数に代入され、<p>
要素がその回数だけ繰り返しレンダリングされます。 - 繰り返し要素の中では、定義した変数 (
item
) や親スコープのデータ (fruits
自体にはアクセスできないが、外側のデータにはアクセス可能) を利用できます。
<li v-for="(user, index) in users">
- 配列の場合、
(要素, インデックス)
の形式で記述すると、要素の値だけでなくそのインデックスも利用できます。 - この例では、
users
配列の各要素(オブジェクト)がuser
に、そのインデックスがindex
に入ります。
- 配列の場合、
<li v-for="(value, key, index) in person">
- オブジェクトの場合、
(値, キー, インデックス)
の形式で記述すると、プロパティの値、プロパティ名(キー)、そしてそのオブジェクトにおけるインデックスを順番に利用できます。 - この例では、
person
オブジェクトの各プロパティが順番に処理されます。
- オブジェクトの場合、
:key="item"
または:key="user.id"
または:key="key"
v-for
を使う際には、必ず:key
属性を指定することが非常に重要です。key
は、Vue.jsがリスト内の各要素を一意に識別するための「目印」です。リストが更新された際に、どの要素が追加・削除・移動されたのかを効率的に追跡し、DOMの再レンダリングを最適化するために使われます。key
には、リスト内で重複しない一意の値(例: データベースのID、配列の要素が文字列ならその文字列自身、オブジェクトのプロパティ名など)を指定します。配列のインデックスをkey
にするのは、要素の順番が頻繁に変わる場合や要素の追加・削除がある場合には推奨されません。
まとめ:主要ディレクティブ
ディレクティブ | 用途 | 省略記法 | 説明 |
---|---|---|---|
{{ }} (テキスト補間) |
テキストの表示 | なし | JavaScriptの式の結果をテキストとして表示。データ変更で自動更新。 |
v-bind:属性名 |
属性の値のバインディング | :属性名 |
要素の属性をデータと紐付ける。class , style , href , src など。 |
v-model |
フォーム入力要素の双方向バインディング | なし | input , textarea , select の値とデータを双方向で紐付ける。 |
v-on:イベント名 |
イベント処理 | @イベント名 |
クリック、入力などイベント発生時にメソッドを実行。イベント修飾子も使える。 |
v-if |
条件付きレンダリング(要素をDOMから削除) | なし | 条件が真の場合に要素をレンダリング。切り替え頻度が低い場合に適する。 |
v-else-if , v-else |
v-if と組み合わせて使用 |
なし | 複数の条件分岐。 |
v-show |
条件付き表示(display: none で制御) |
なし | 条件が真の場合に表示。切り替え頻度が高い場合に適する。要素は常にDOMに存在する。 |
v-for="変数 in リスト" |
リストレンダリング | なし | 配列やオブジェクトの要素を繰り返し表示。:key 属性は必須。 |
これらのディレクティブを組み合わせることで、データに基づいて動的に変化するUIを構築できます。
算出プロパティ (Computed Properties) とウォッチャ (Watchers)
Vue.jsでは、データに基づいて計算された値を扱ったり、特定のデータの変更を監視して処理を実行したりするための機能が提供されています。それが「算出プロパティ」と「ウォッチャ」です。
どちらもデータの変更に対応する機能ですが、使い分けがあります。
算出プロパティ (Computed Properties)
算出プロパティは、既存のデータから新しい値を「計算して」取得したい場合に使います。計算結果はキャッシュされ、依存しているデータが変更されない限り再計算されません。これにより、無駄な計算を防ぎ、パフォーマンスが向上します。
例えば、firstName
と lastName
というデータから fullName
を生成する場合などです。
“`html
名:
姓:
フルネーム (算出プロパティ): {{ fullName }}
フルネーム (メソッド): {{ getFullNameMethod() }}
“`
ブラウザの開発者コンソールを開いて、入力フィールドに文字を入力してみてください。
fullNameが再計算されました
は、firstName
またはlastName
が変更されたときにだけ表示されます。getFullNameMethodが実行されました
は、入力するたびに(あるいはテンプレートが再レンダリングされるたびに)表示されます。
これがキャッシュの効果です。算出プロパティはプロパティとしてテンプレートから参照し ({{ fullName }}
)、メソッドは関数として呼び出します ({{ getFullNameMethod() }}
)。
算出プロパティを使うべき場面:
- 複数のデータから一つの値を計算したい場合。
- 計算結果をキャッシュしておきたい場合(依存データが変わらない限り再計算しない)。
- テンプレート内で複雑なロジックを避けたい場合(テンプレートを読みやすくする)。
ウォッチャ (Watchers)
ウォッチャは、特定のデータプロパティの変更を監視し、その変更が起きたときに非同期処理やコストのかかる処理を実行したい場合に使います。データの変更に応じて、何か特定の「副作用」を引き起こしたい場合に適しています。
例えば、「入力フィールドに特定の単語が入力されたら、サーバーに問い合わせてサジェストを表示する」といった処理です。
“`html
質問を入力してください:
{{ answer }}
“`
解説:
watch: { ... }
- これは「ウォッチャオプション」です。監視したいデータプロパティと同名の関数を定義します。
question(newQuestion, oldQuestion) { ... }
question
というデータプロパティの値が変更されるたびに、この関数が実行されます。- 関数は2つの引数を受け取ります: 変更後の新しい値 (
newQuestion
) と変更前の古い値 (oldQuestion
)。 - この例では、入力された質問に「?」が含まれているかをチェックし、非同期で答えを設定しています。
ウォッチャを使うべき場面:
- データの変更に応じて、DOMの操作や非同期処理(API呼び出しなど)といった「副作用」を実行したい場合。
- 複数のデータプロパティや複雑なロジックに基づいて副作用を実行したい場合。
算出プロパティ vs ウォッチャ まとめ
特徴 | 算出プロパティ (Computed) | ウォッチャ (Watch) |
---|---|---|
用途 | データから新しい値を計算し、表示 | データ変更に応じて副作用(非同期処理など)を実行 |
戻り値 | 計算された値(テンプレートで使用) | なし(副作用を引き起こす) |
キャッシュ | あり(依存データが変わらない限り再利用) | なし(変更のたびに実行) |
依存関係 | 暗黙的(コード内で使用しているデータ) | 明示的(監視対象のプロパティを指定) |
処理の複雑さ | 同期的な計算に適する | 非同期処理や複雑なロジックに適する |
原則として、データから新しい値を計算して表示したいだけであれば算出プロパティを、データの変更に応じて何か特定の副作用を引き起こしたい場合はウォッチャを使う、と覚えておくと良いでしょう。算出プロパティで実現できることをウォッチャで実現することも可能ですが、算出プロパティの方が意図が明確で、キャッシュの恩恵も受けられます。
Vueコンポーネント入門
Vue.jsの最も強力で中心的な機能の一つが「コンポーネント」です。コンポーネントを使うことで、UIを独立した、再利用可能な部品に分割し、アプリケーション全体を部品の組み合わせとして構築できます。
先ほどまでの例は、一つの大きなVueインスタンスで全てを管理していましたが、実際の複雑なアプリケーションでは、UIを「ヘッダー」「サイドバー」「ボタン」「モーダルウィンドウ」「ToDoリストアイテム」といった小さな部品に分割し、それぞれをコンポーネントとして作成します。
なぜコンポーネントが必要なのか?
- 再利用性: 一度作ったコンポーネントは、アプリケーションのどこでも、何度でも使い回せます。
- 管理のしやすさ: 各コンポーネントは独立しているため、一つの部品の変更が他の部品に影響を与えにくく、コードが追いやすくなります。
- 可読性: アプリケーション全体が部品の組み合わせとして表現されるため、構造が理解しやすくなります。
- 保守性: バグが発生した場合も、どの部品に問題があるのか特定しやすくなります。
- 開発効率: 複数人で開発する場合、担当するコンポーネントを決めて並行して作業できます。
コンポーネントの基本構造
コンポーネントも基本的にVueインスタンスと同じオプション(data
, methods
, computed
, watch
など)を持つことができます。ただし、コンポーネントの data
オプションは必ず関数として定義し、オブジェクトを返す必要があります。これは、コンポーネントが複数箇所で使われた場合に、それぞれのインスタンスが独立したデータを持つようにするためです。
グローバル登録とローカル登録
コンポーネントをVueアプリケーションで使えるようにするには、「登録」が必要です。登録には「グローバル登録」と「ローカル登録」の2種類があります。
- グローバル登録: 一度登録すれば、そのVueアプリケーション内のどこでも(どのコンポーネントのテンプレートでも)使えるようになります。
- ローカル登録: 特定の親コンポーネント内でだけ使えるようにします。使わないコンポーネントを読み込まないため、ビルド時のファイルサイズを小さく保てます。
Vue 3では、パフォーマンスと管理のしやすさからローカル登録が推奨されています。入門としてはグローバル登録の方がシンプルなので、まずはこちらから見ていきましょう。
グローバル登録 (Vue 3)
createApp
で作成したアプリケーションインスタンスの component
メソッドを使って登録します。
“`html
グローバルコンポーネントの例
“`
解説:
- コンポーネントの定義: 通常のVueインスタンスオプションを持つJavaScriptオブジェクトとしてコンポーネントの定義を作成します。
template
プロパティでそのコンポーネントのHTML構造を記述します。 - グローバル登録:
app.component('タグ名', 定義オブジェクト)
の形式で、アプリケーションインスタンスにコンポーネントを登録します。タグ名はカスタム要素の名前として使用します。HTMLとの衝突を避けるため、ケバブケース(-
でつなぐ)で記述するのが慣習です。 - コンポーネントの使用: 登録したタグ名をHTMLテンプレート内で通常のHTML要素のように使用します (
<my-button></my-button>
)。Vueがこのカスタムタグを見つけると、登録されたコンポーネントのテンプレートとロジックで置き換えます。
props: 親から子へデータを渡す
コンポーネントは独立していますが、親子の関係でデータをやり取りする必要があります。親コンポーネントから子コンポーネントへデータを渡すには、「プロパティ(props)」を使います。
子コンポーネントの定義で props
オプションを指定し、受け取りたいプロパティ名を配列またはオブジェクトで列挙します。親コンポーネントのテンプレートでは、子コンポーネントを使う際に v-bind
または :
を使ってデータを渡します。
上記の GreetingMessageComponent
の例を見てみましょう。
- 子コンポーネント (
GreetingMessageComponent
) の定義:
javascript
const GreetingMessageComponent = {
props: ['name'], // 'name'というプロパティを受け取る
template: `
<p>こんにちは、{{ name }}さん!</p>
`
};
props: ['name']
と定義することで、このコンポーネントはname
というプロパティを受け取れるようになります。テンプレート内では、受け取ったプロパティをデータのように{{ name }}
やthis.name
で使用できます。 - 親(ルートインスタンス)のテンプレートでの使用:
html
<greeting-message name="太郎"></greeting-message>
<greeting-message :name="'花子'"></greeting-message> <!-- またはデータから渡す -->
子コンポーネントを使うHTMLタグに、属性としてプロパティ名を指定します。属性の値は、静的な文字列 (name="太郎"
) でも、v-bind
を使ったデータバインディング (:name="parentData"
) でも可能です。v-bind
を使うと、親のデータが更新されたときに子のプロパティも自動的に更新されます。
カスタムイベント: 子から親へデータを渡す
子コンポーネントで起きた出来事(イベント)を親コンポーネントに伝えたい場合は、カスタムイベントを発行(emit)します。親コンポーネントは、子のカスタムイベントを監視し、発生したら特定のメソッドを実行します。
例:子コンポーネント内のボタンがクリックされたことを親に伝えたい場合。
“`html
カスタムイベントの例
親のカウント: {{ parentCount }}
“`
解説:
- 子コンポーネント (
MyCounterComponent
) の定義:methods
内のincrementLocal
関数でthis.$emit('increment-event');
を呼び出しています。this.$emit()
は、指定した名前 ('increment-event'
) のカスタムイベントを発行するためのメソッドです。第2引数以降で、イベントと一緒にデータを親に渡すこともできます。
- 親(ルートインスタンス)のテンプレートでの使用:
- 子コンポーネントを使うタグに
v-on
(または@
) ディレクティブを使って、子コンポーネントが発行するイベント名を監視します。 @increment-event="handleIncrement"
は、「my-counter
からincrement-event
というイベントが発生したら、親のhandleIncrement
メソッドを実行する」という意味になります。
- 子コンポーネントを使うタグに
このように、props
で親から子へ、カスタムイベントで子から親へデータを渡すのが、Vue.jsにおけるコンポーネント間の基本的なデータフローです。これは「単方向データフロー」と呼ばれ、データの流れが予測しやすいため、アプリケーションの状態管理がしやすくなるというメリットがあります。
Single File Components (SFC) について(CLI 環境)
これまでの例では、HTMLファイル内にJavaScriptの <script>
タグでコンポーネントの定義やVueアプリケーションのコードを書いていました。これは学習の初期段階では良いですが、実際の開発ではコード量が多くなり、管理が難しくなります。
そこで、Vue.jsの開発では「Single File Components (SFC)」、つまり .vue
という拡張子を持つ単一ファイルでコンポーネントを記述する方法が一般的です。
.vue
ファイルは、一つのファイルの中に、そのコンポーネントの
<template>
: HTML構造<script>
: JavaScriptのロジック (データ、メソッドなど)<style>
: CSSスタイル
を記述できます。
例:MyComponent.vue
“`vue
{{ title }}
{{ message }}
“`
この .vue
ファイルは、そのままではブラウザで解釈できません。そのため、WebpackやViteといった「ビルドツール」を使って、ブラウザが理解できるHTML, CSS, JavaScriptの形式に変換する必要があります。
このビルドツールの設定やプロジェクト構造を簡単に整えてくれるのが、Vue CLI (Vue 2 まで) や Vite (Vue 3 以降の推奨) といった「スキャフォールディングツール」です。
Vue CLI / Vite を使った環境構築
Vue.jsの本格的な開発を始めるには、Node.jsがインストールされた環境で、Viteを使ってプロジェクトを作成するのが最も一般的です。
- Node.jsのインストール: Vue.jsのエコシステムはNode.js上で動きます。公式サイトからLTS版をダウンロードしてインストールしてください。インストールすると、
node
コマンドとnpm
(Node Package Manager) またはyarn
コマンドが使えるようになります。 -
Viteのインストールとプロジェクト作成: ターミナル(コマンドプロンプトやPowerShellなど)を開き、以下のコマンドを実行します。
bash
npm create vue@latest
または
bash
yarn create vue@latest
または
bash
pnpm create vue@latestコマンドを実行すると、プロジェクト名、TypeScriptを使うか、Vue RouterやPiniaなどのライブラリを追加するかなどを質問されます。指示に従って選択していくと、Vue.jsアプリケーションの基本的なプロジェクト構造が自動的に作成されます。
-
プロジェクトの起動: 作成されたプロジェクトフォルダに移動し、依存関係をインストールして開発サーバーを起動します。
bash
cd your-project-name # (作成したプロジェクト名)
npm install # または yarn install, pnpm install
npm run dev # または yarn dev, pnpm devこれで、ローカルの開発サーバーが起動し、ブラウザでアプリケーションを確認できるようになります。コードを変更すると、多くの場合自動的にブラウザの表示も更新されます(ホットリロード)。
SFCとビルドツールを使う環境は、開発効率が格段に向上するため、入門の基本的な構文を理解したら、すぐにこの環境に移行することをおすすめします。以降の解説は、このSFC環境を前提とします。
Vue 3 の主要機能(Options API と Composition API)
Vue 3は、Vue 2から多くの改善が加えられたメジャーバージョンアップです。特に大きな変更点は「Composition API」の導入ですが、Vue 2までの書き方である「Options API」も引き続きVue 3で利用可能です。
この入門記事では、初心者にとって直感的で理解しやすいOptions APIを中心に解説してきましたが、現代のVue.js開発ではComposition APIが主流になりつつあります。両者の違いと、Options APIがどのようにVue 3で使われるのかを簡単に見ていきましょう。
Options API (Vue 2までの書き方、Vue 3でも利用可能)
Options APIは、これまで見てきたように、コンポーネントのロジックを data
, methods
, computed
, watch
, props
といった「オプション」ごとにまとめて記述するスタイルです。
“`vue
“`
このスタイルは、コンポーネントの機能がシンプルなうちは分かりやすいですが、コンポーネントが複雑になり、様々なロジック(例えば、フォーム入力関連、リスト表示関連、モーダル表示関連など)が混在してくると、それぞれのロジックに関連するコード(データ、メソッド、ウォッチャなど)がファイル内のあちこちに分散してしまい、コードを追いかけるのが難しくなるという課題がありました。
Composition API (Vue 3 で導入された新しい書き方)
Composition APIは、コンポーネントのロジックを機能ごとにまとめて記述できる新しいスタイルです。setup()
関数の中でリアクティブな状態 (ref
, reactive
) や関数 (computed
, watch
, onMounted
など) を定義し、それらをまとめて return
するという書き方をします。
“`vue
“`
Composition APIの利点:
- コードの整理: 関連するロジック(データ、算出プロパティ、ウォッチャ、ライフサイクルフックなど)をまとめて記述できるため、コンポーネントが複雑になってもコードが追いやすい。
- ロジックの再利用: 共通のロジックを関数として切り出し、複数のコンポーネントで使い回すことが容易になる(Custom Hooksのようなもの)。
- TypeScriptとの相性が良い: 型推論が効きやすく、より堅牢なコードを書ける。
初めはOptions APIの方が概念的に分かりやすいかもしれませんが、実際のプロジェクト開発ではComposition APIが主流です。基本的な概念を理解したら、Composition APIの学習に進むことを強くお勧めします。
Vue 3では、Options APIとComposition APIを一つのコンポーネント内で混在させることも可能ですが、一般的にはどちらか一方に統一することが推奨されます。
ライフサイクルフック (Lifecycle Hooks)
Vueコンポーネントは、作成されてから画面に表示され、更新され、そして破棄されるまで、一連のライフサイクル(生命周期)をたどります。このライフサイクルの特定の段階で、独自のコードを実行するための仕組みが「ライフサイクルフック」です。
例えば、「コンポーネントが作成された直後にデータを取得する」「画面に表示された後に何か処理を行う」「コンポーネントが破棄される前に後片付けをする」といった処理で利用します。
Options APIにおける主なライフサイクルフック:
beforeCreate
: インスタンスが初期化され、データやイベントの設定が行われる直前。created
: インスタンスが作成され、データやイベントが設定された後。テンプレートはまだマウントされていない。データを使って何か処理をしたり、非同期処理(API呼び出し)をしたりするのに適している。beforeMount
: テンプレートがDOMにマウントされる直前。mounted
: テンプレートがDOMにマウントされた後。コンポーネントが初めて画面に表示された状態。DOMにアクセスする必要がある処理や、サードパーティライブラリの初期化などに適している。beforeUpdate
: データが更新され、DOMが再描画される直前。updated
: データが更新され、DOMが再描画された後。DOMにアクセスする際は注意が必要(無限ループになる可能性)。beforeUnmount
: インスタンスがアンマウント(破棄)される直前。unmounted
: インスタンスがアンマウントされた後。コンポーネントがDOMから完全に削除された状態。イベントリスナーの解除やタイマーのクリアなど、後片付けを行うのに適している。
ライフサイクルフックの例:
“`vue
{{ message }}
“`
このコンポーネントをアプリケーションに表示/非表示したり、データを更新したりすると、コンソールにそれぞれのフックが実行されるタイミングが表示されます。
ライフサイクルフックは、コンポーネントの振る舞いを細かく制御するために非常に重要な概念です。
Vue Router: シングルページアプリケーション (SPA) のルーティング
ウェブサイトにおいて、「ルーティング」とは、ユーザーが特定のURLにアクセスしたときに、どのコンテンツ(ページ)を表示するかを決定する仕組みです。
従来のウェブサイトでは、異なるURLにアクセスするとサーバーが新しいHTMLファイルを応答し、ブラウザがページ全体を再読み込みしていました。
シングルページアプリケーション (SPA) では、ページ遷移しても基本的にHTMLファイルを再読み込みせず、JavaScriptが動的にコンテンツを切り替えます。URLだけが変化し、あたかもページ遷移したかのように見せかけます。このSPAにおけるルーティングを実現するための公式ライブラリがVue Routerです。
Vue Routerを使うと、以下のようなことができるようになります。
- URLとVueコンポーネントを紐付ける。
<router-link>
というコンポーネントを使って、ページ全体を再読み込みせずにナビゲーションリンクを作成する。<router-view>
というコンポーネントを使って、現在のURLに対応するコンポーネントを表示するエリアを指定する。- URLに含まれるパラメータ(例:
/users/123
の123
)を取得してコンポーネントに渡す。 - ナビゲーションガード(特定のページへのアクセス制限など)を設定する。
Vue Routerは公式ライブラリなので、Viteでプロジェクトを作成する際にオプションとして追加できます。
基本的な設定の考え方:
- ルーターインスタンスの作成: どのURLでどのコンポーネントを表示するかを定義した「ルート設定」の配列を元に、ルーターインスタンスを作成します。
- Vueアプリケーションへの追加: 作成したルーターインスタンスをVueアプリケーションに組み込みます。
- ルータービューとリンクの設置: アプリケーションのテンプレート内で、
<router-view>
タグを置いてコンテンツ表示エリアを、<router-link>
タグを使ってナビゲーションリンクを作成します。
簡単なコード例 (ViteでVue Routerを追加した場合の router/index.js
のようなファイル):
“`javascript
import { createRouter, createWebHistory } from ‘vue-router’;
import HomeView from ‘../views/HomeView.vue’; // HomeView.vue というコンポーネントをインポート
import AboutView from ‘../views/AboutView.vue’; // AboutView.vue というコンポーネントをインポート
// ルート設定の定義
const routes = [
{
path: ‘/’, // URLのパス
name: ‘home’, // ルートの名前 (オプション)
component: HomeView // 表示するコンポーネント
},
{
path: ‘/about’,
name: ‘about’,
component: AboutView // 別コンポーネント
// 別の書き方: component: () => import(‘../views/AboutView.vue’) // 必要になったときに遅延ロード (より高速)
}
// 他のルートもここに追加
];
// ルーターインスタンスの作成
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), // ルーティング履歴のモード (createWebHistoryが一般的)
routes // 定義したルート設定
});
// Vueアプリケーションで使えるようにエクスポート
export default router;
“`
Vueアプリケーションへの組み込み (main.js
のようなファイル):
“`javascript
import { createApp } from ‘vue’;
import App from ‘./App.vue’; // ルートコンポーネント
import router from ‘./router’; // 作成したルーターインスタンスをインポート
const app = createApp(App); // Vueアプリケーションインスタンス作成
app.use(router); // ルーターをアプリケーションで使用可能にする
app.mount(‘#app’); // アプリケーションをマウント
“`
アプリケーションのルートコンポーネント (App.vue
のようなファイル):
“`vue
```
このように、Vue Routerを使うことで、SPAにおける複雑な画面遷移を宣言的に、かつ効率的に管理できるようになります。
Pinia: 状態管理ライブラリ
アプリケーションの規模が大きくなってくると、複数のコンポーネント間で共通のデータを共有したり、アプリケーション全体で管理すべき状態(例: ログインユーザー情報、カートの内容、テーマ設定など)が出てきます。
このような「アプリケーション全体で共有される状態」を管理するためのパターンやライブラリを「状態管理」と呼びます。Vue.jsの公式な状態管理ライブラリとしては、Vuex(Vue 2まで主流)とPinia(Vue 3の推奨)があります。
PiniaはVuexよりもシンプルで使いやすく、Vue 3のComposition APIとの相性が良いように設計されています。
なぜ状態管理が必要なのか?
コンポーネント間でデータを共有する基本的な方法は、props
で親から子へ、カスタムイベント ($emit
) で子から親へ渡すことです。しかし、コンポーネントの階層が深くなったり、親子関係にないコンポーネント間でデータをやり取りしたりする場合、この方法は非常に煩雑になります(「props drilling」と呼ばれる問題)。
Piniaのような状態管理ライブラリを使うと、共有したい状態を一箇所(ストア)に集約し、どのコンポーネントからでもその状態にアクセスしたり、変更したりできるようになります。
Piniaの基本的な考え方
Piniaでは、「ストア (Store)」という概念を使って状態を管理します。一つのアプリケーションに複数のストアを持つことができます(例えば、ユーザー関連のストア、商品関連のストアなど)。
各ストアは、以下の3つの要素を持ちます。
- State: アプリケーションの状態を表すデータ。
- Getters: Stateから計算された値を取得するためのもの(Vueコンポーネントの算出プロパティに似ています)。
- Actions: Stateを変更するためのロジックや非同期処理を含むもの(Vueコンポーネントのメソッドに似ています)。
簡単なコード例 (ViteでPiniaを追加した場合の stores/counter.js
のようなファイル):
```javascript
import { defineStore } from 'pinia';
// 'counter'というIDでストアを定義
export const useCounterStore = defineStore('counter', {
// 状態 (State)
state: () => ({
count: 0,
name: 'Eduardo',
}),
// ゲッター (Getters) - Stateから派生した値を計算
getters: {
doubleCount: (state) => state.count * 2, // stateを引数として受け取る
// 他のゲッターやstateにアクセスすることも可能
doubleCountPlusOne() {
return this.doubleCount + 1; // thisで他のgetterやstateにアクセス
},
},
// アクション (Actions) - Stateを変更するロジックや非同期処理
actions: {
increment(value = 1) { // 引数を受け取ることも可能
this.count += value; // thisでstateにアクセス
},
// 非同期処理の例
// async fetchNewCount() {
// const res = await fetch('...');
// this.count = await res.json();
// }
},
});
```
Vueアプリケーションへの組み込み (main.js
のようなファイル):
```javascript
import { createApp } from 'vue';
import { createPinia } from 'pinia'; // Piniaインスタンスを作成する関数をインポート
import App from './App.vue';
const app = createApp(App);
const pinia = createPinia(); // Piniaインスタンスを作成
app.use(pinia); // Piniaをアプリケーションで使用可能にする
app.mount('#app');
```
コンポーネントでのストアの利用 (SomeComponent.vue
のようなファイル):
```vue
Pinia Counter
Count: {{ counterStore.count }}
Double Count: {{ counterStore.doubleCount }}
```
このように、Piniaを使うことで、アプリケーション全体で共有される状態を一元管理し、どのコンポーネントからでも簡単にアクセス・変更できるようになります。これにより、複雑なアプリケーションの状態管理が格段に楽になります。
Vue.jsの開発者ツール
Vue.jsでの開発を強力にサポートしてくれるのが、ブラウザの拡張機能である「Vue.js devtools」です。
ChromeやFirefoxなどのブラウザにこの拡張機能をインストールすると、開発者ツールのパネルに「Vue」というタブが追加されます。このタブを開くと、以下のような情報を確認できます。
- コンポーネントツリー: アプリケーション内のコンポーネントが親子関係を含めてツリー形式で表示されます。
- コンポーネントの状態: 選択したコンポーネントの
data
,props
,computed
などの現在の値を確認、編集できます。値を編集すると、リアルタイムに画面表示も更新されます。 - Vuex / Pinia ストア: ストアの状態を確認・編集したり、ミューテーション(状態変更の履歴)を追跡したりできます。
- イベント: コンポーネント間で発生したカスタムイベントなどを確認できます。
Vue.js devtoolsを使うと、アプリケーションの内部状態を「見える化」できるため、デバッグ作業が非常に効率的になります。開発時には必ずインストールして活用することをお勧めします。
Vue.jsのメリット・デメリット
メリット
- 学習しやすい: HTML, CSS, JavaScriptの基本があれば比較的スムーズに始められます。公式ドキュメントも分かりやすく充実しています。
- パフォーマンス: 仮想DOM(Virtual DOM)を採用しており、効率的なDOM更新により高いパフォーマンスを実現します。
- 柔軟性: ライブラリとして小さく始められ、必要に応じて公式ルーターや状態管理ライブラリを追加するなど、段階的に導入できます。既存のプロジェクトの一部に組み込むことも容易です。
- 充実したエコシステム: 公式ルーター (Vue Router)、公式状態管理ライブラリ (Pinia / Vuex)、公式ビルドツール (Vite)、開発者ツール (Vue.js devtools) など、必要なツールが一通り揃っています。
- 日本語ドキュメント: 公式ドキュメントを含む多くの情報が日本語で提供されています。
- 人気とコミュニティ: 世界的にも日本国内でも人気が高く、活発なコミュニティがあります。困ったときに質問しやすい環境です。
デメリット
- Reactと比較した情報量/求人数: 世界的にはReactの方がユーザー数が多く、情報量や求人数が多い傾向があります(ただし、Vue.jsも十分に多く、特に国内では強いです)。
- 柔軟性ゆえの規約の自由度: Options APIは書き方の自由度が高いため、チーム開発などではコーディング規約をしっかり定める必要があります(Composition APIはより構造化しやすい傾向があります)。
多くのプロジェクトにおいて、Vue.jsは非常に有力な選択肢となり得ます。特に、フロントエンドフレームワークに初めて触れる方にとっては、学習コストが低い点が大きな魅力です。
次のステップ
この記事では、Vue.jsの最も基本的な部分(インスタンス作成、テンプレート構文、主要ディレクティブ、コンポーネントの基本、ライフサイクル、Vue 3のAPIスタイル、ルーティング、状態管理の概要)を網羅しました。
これだけでも簡単なアプリケーションは作れるようになりますが、実際の開発ではさらに多くの知識や技術が必要になります。
- Composition API: 現代のVue.js開発の主流であるComposition APIを本格的に学びましょう。
- より高度なコンポーネント設計: Slots(コンポーネントにコンテンツを埋め込む)、非同期コンポーネント、レンダー関数など。
- フォームハンドリング: より複雑なフォーム入力の検証など。
- API通信: サーバーからデータを取得したり送信したりする方法(fetch APIやAxiosライブラリなど)。
- テスト: コンポーネントのテスト方法(Unitテスト、Integrationテスト)。
- デプロイ: 作成したアプリケーションをインターネット上に公開する方法。
- サーバーサイドレンダリング (SSR) / 静的サイト生成 (SSG): SEOやパフォーマンス向上のための技術(Nuxt.jsというフレームワークがVue.jsをベースにこれらの機能を提供しています)。
- TypeScript: より大規模なアプリケーション開発でコードの品質を高めるために有効です。
学習を進める上で最も重要なのは、実際にコードを書いてみることです。小さなアプリケーションでも良いので、この記事で学んだことを活かして何か作ってみましょう。公式ドキュメントは非常に質が高いので、リファレンスとしても積極的に活用してください。
まとめ
Vue.jsは、インタラクティブなユーザーインターフェースを効率的に構築するための、学びやすく強力なJavaScriptフレームワークです。
- JavaScriptのデータを画面に自動的に反映させるリアクティビティを持っています。
- UIを再利用可能なコンポーネントに分割して開発できます。
v-
プリフィックスから始まるディレクティブを使って、データとDOMを様々な形でバインディングします (v-bind
,v-model
,v-if
,v-for
,v-on
など)。- データから値を計算する算出プロパティと、データの変更を監視するウォッチャを使い分けます。
- コンポーネント間は、props(親→子)とカスタムイベント(子→親)でデータをやり取りします。
- Vue 3では、 Options APIに加えて、ロジックを機能ごとにまとめやすいComposition APIが導入されました。
- コンポーネントにはライフサイクルフックがあり、特定のタイミングでコードを実行できます。
- シングルページアプリケーションのルーティングには公式のVue Router、アプリケーション全体の状態管理には公式のPinia(Vue 3推奨)というライブラリがあります。
- ブラウザの開発者ツール拡張機能であるVue.js devtoolsは開発に不可欠です。
この記事が、あなたのVue.js学習の第一歩となり、ウェブ開発の楽しさをさらに広げる助けになれば幸いです。
頑張ってください!そして、Happy Coding!