Vue.jsについて1から学ぶ
初めに
Vue.jsについて、学ぶ機会があったので、軽くまとめていきたいと思います。
(初心者のため優しい目で見てください)
この記事は以下についてまとめています。
- アプリケーションインスタンス(createApp)
- データバイディング
- ディレクティブ
- 双方向データバインディングとは?
- computedについて
- watchについて
Vue.jsとは?
Vue.jsは、JavaScriptで動的なWebアプリケーションを作るためのフロントエンド・フレームワークです。
アプリケーションインスタンス(createApp)
Vue 3 では createApp 関数を使って「アプリケーションインスタンス」を作成し、その中でルートコンポーネントを登録してマウントします。
データバインディング ({{ }})
データバインディングは、アプリケーションインスタンスのデータをHTMLに表示する仕組みです。テキスト補間とも呼ばれ、{{ }}
(マスタッシュ構文)を使います。
ディレクティブ
ディレクティブは、v-というプレフィックスを持つ特殊なHTML属性で、DOM(Document Object Model)に特定の振る舞いをさせます。
v-bind
- リアクティブデータを HTML 要素の属性に反映させます。短縮形は
:
- 構文
v-bind:属性名="プロパティ名"
- 簡単な例
<template>
<img v-bind:src="imageUrl" alt="写真">
<!-- 省略形 -->
<img :src="imageUrl" alt="写真">
</template>
<script setup>
const imageUrl = 'https://example.com/pic.png'
</script>
v-if
/ v-else
/ v-show
-
v-if
は、条件がtrueの場合に要素をレンダリング(DOMに追加)し、falseの場合はDOMから完全に削除します。これにより、要素が存在しなくなります。-
v-if
条件がtrueの場合にのみ、要素をDOMに挿入します。 -
v-else-if
v-ifの条件がfalseだった場合に、次の条件を評価します。 -
v-else
上記すべての条件がfalseだった場合に表示されます。
-
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else>
C
</div>
v-show
も要素の表示・非表示を制御しますが、常にDOMに要素が存在します。条件がfalseの場合、CSSのdisplay: none;
を適用することで非表示にします。要素が頻繁に切り替わる場合に適しています。
-
v-if
を使う時- 要素の表示切替がまれ
- 初期描画時に非表示で良い(DOM を作らない方が軽い)
- 非表示中は内部状態やイベントリスナーも不要にしたい場合
-
v-show
を使う時- 要素を頻繁に表示/非表示する(例:タブ切り替え、アコーディオンメニュー)
- 内部状態やフォーム入力値を保持したまま非表示にしたい場合
v-for
- 役割は、JavaScriptの配列やオブジェクトのデータに基づいて、HTMLの要素を自動的に複数生成することです。これにより、手動で同じようなHTMLを何度も書く手間が省けます。key は基本的にユニークな識別子を渡す必要があります。
<template>
<ul>
<li v-for="fruit in fruits" :key="fruit.id">
{{ fruit.name }}
</li>
</ul>
</template>
<script setup>
const fruits = [
{ id: 1, name: 'りんご' },
{ id: 2, name: 'バナナ' },
{ id: 3, name: 'ぶどう' }
]
</script>
v-on (イベントハンドリング)
- ユーザーの操作(クリック、キー入力、ホバーなど)に対応して、テンプレートから呼び出せる関数のことです。これにより、イベントに応じた動的な振る舞いをアプリケーションに持たせることができます。
- 簡単な例
<button v-on:click="handleClick">クリックしてください</button>
- 省略形
v-on
は頻繁に使用されるため、省略記法としてアットマーク@
を使うことができます。
<button @click="handleClick">クリックしてください</button>
双方向データバインディングとは?
JavaScript のデータと HTML の表示(UI)が、お互いにリアクティブに同期される仕組みです。
つまり…
ユーザーが画面に入力した内容は即座にデータに反映され、
データが変更されれば、画面の表示も自動で更新される。
この両方向の同期が 双方向データバインディング です。
種類 | 説明 |
---|---|
一方向バインディング | データ → 画面だけの更新(例: {{ message }} ) |
双方向バインディング | データ ↔ 画面の両方が同期(例: v-model ) |
computedについて
-
computed
は算出プロパティ(computed property) と呼ばれています。 - データや他の状態から派生した値を定義するために使います。
- 単純に関数を呼び出してもいいのですが、computed を使うと以下のメリットがあります。
- 必要に応じて再計算される → 依存している値が変わったときにだけ再計算され、それ以外のときは前回の結果を使う。
- 宣言的に書ける → 「この値はこの状態から自動的に計算される」と明確にできる。
例1
<script setup>
import { ref, computed } from 'vue'
// 基本データ
const firstName = ref('Hoge')
const lastName = ref('Hogehoge')
// 算出プロパティ
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`
})
</script>
<template>
<p>姓: <input v-model="firstName" /></p>
<p>名: <input v-model="lastName" /></p>
<p>フルネーム: {{ fullName }}</p>
</template>
解説
- firstName や lastName を更新すると、fullName も自動で更新されます。
- computed は依存している値 (firstName, lastName) が変わらない限り再評価されません。
実行結果
getter
/setter
付き)
例2(<script setup>
import { ref, computed } from 'vue'
const firstName = ref('Hoge')
const lastName = ref('Hogehoge')
const fullName = computed({
get() {
return `${firstName.value} ${lastName.value}`
},
set(newValue) {
const parts = newValue.split(' ')
firstName.value = parts[0] || ''
lastName.value = parts[1] || ''
}
})
</script>
<template>
<input v-model="fullName" />
<p>姓: {{ firstName }}</p>
<p>名: {{ lastName }}</p>
</template>
解説
この場合、<input v-model="fullName" /> に入力すると firstName と lastName にも反映されます。
実行結果
getter
/setter
あり・なしの違いを整理してみる。
-
getter
だけのcomputed
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`
})
-
getter
/setter
両方あるcomputed
const fullName = computed({
get() {
return `${firstName.value} ${lastName.value}`
},
set(newValue) {
const parts = newValue.split(' ')
firstName.value = parts[0] || ''
lastName.value = parts[1] || ''
}
})
まとめると、、、、
-
getter
のみ
「フルネームを表示したい」だけ。入力は firstName と lastName に直接する。 -
getter
+setter
「フルネームを1つの input で編集したい」。fullName を直接更新すると裏で firstName とlastName に分解されて反映される。
watchについて
-
watch
は指定したリアクティブな値を監視して、副作用を実行するための仕組みです。 - 「値の変化に応じて何か処理したいとき」に使います。
- 似ている
computed
は「新しい値を返す」ために使うのに対し、watch
は「値が変わったときに処理を走らせる」ために使います。
ref
を監視)
例1(<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
watch(count, (newValue, oldValue) => {
console.log(`count が ${oldValue} から ${newValue} に変わりました!`)
})
</script>
<template>
<button @click="count++">カウントアップ</button>
<p>{{ count }}</p>
</template>
実行結果
- count が変わるたびにコールバックが呼ばれる。
- watch のコールバック引数には 新しい値・古い値 が渡される。
例2(複数の値の変化に応じて処理を実行)
今回は、「複数の値で条件分岐して背景色を変更する」ケース。
<script setup>
import { ref, watch } from 'vue'
const temperature = ref(20)
const humidity = ref(50)
const backgroundColor = ref('white')
watch([temperature, humidity], ([temp, hum]) => {
if (temp > 30 && hum > 70) {
backgroundColor.value = 'red'
} else if (temp < 10) {
backgroundColor.value = 'blue'
} else {
backgroundColor.value = 'green'
}
})
</script>
<template>
<div :style="{ backgroundColor: backgroundColor, padding: '20px' }">
<p>Temperature: <input type="number" v-model="temperature" />℃</p>
<p>Humidity: <input type="number" v-model="humidity" />%</p>
</div>
</template>
解説
- watch に配列を渡すことで、複数の 値を同時に監視できます。
- v-model でバインドされた入力が変わるたびに watch が呼ばれるので、背景色が即座に更新されます。
実行結果
Discussion