はじめに
これまでの記事でVue.jsの環境構築、基本構文、非同期処理の方法までを解説しました。
環境構築

Vue.js入門:特徴から環境構築まで完全ガイド
Vue.jsの基本から環境構築まで初心者向けにわかりやすく解説!CDN版とVue CLIの違い、セットアップ方法、便利なツールも紹介します。
基本構文

Vue.jsの基本構文からコンポーネントの使い方まで解説
Vue.jsの基本構文からコンポーネントの使い方まで初心者向けに詳しく解説。簡単なサンプルコード付きで、実践しながら学べます。
非同期処理

Vue 3でAPI連携!fetchとAxiosの使い方
Vue 3でAPIからデータを取得する方法を初心者向けに解説!fetchとAxiosの違い、非同期処理、エラーハンドリングの実装方法を紹介。
構文だけでは開発イメージが持てないと思うので、Vue 3 を使って簡単なアプリを作成する方法を解説します!
TODOリストアプリの作成(ローカルストレージ利用)
Vue 3 の ref()
を使ってタスクを管理し、localStorage
を活用してデータを保持する TODOリストアプリ を作成します。
ページをリロードしてもタスクが消えないように localStorage
を利用し、基本的な CRUD(追加・削除・保持)機能を実装します。
プロジェクトディレクトリ
todo-app/
│── public/
│── src/
│ ├── assets/
│ ├── components/
│ │ ├── TodoList.vue ← TODOリストのコンポーネント
│ ├── App.vue ← メインレイアウト
│ ├── main.js ← Vue インスタンスの作成
│ ├── store.js ← (オプション) 状態管理を使う場合
│── package.json
│── vite.config.js (または vue.config.js)
│── index.html
TODOリストの詳細な実装
実装する機能
- タスクの追加
- タスクの削除
- ローカルストレージに保存し、リロードしてもデータを保持
App.vue(メインレイアウト)
<script setup>
import TodoList from './components/TodoList.vue';
</script>
<template>
<div>
<h1>Vue 3 TODOリスト</h1>
<TodoList />
</div>
</template>
TodoList.vue
を コンポーネントとして読み込む ことで、構成を整理しています。
TodoList.vue(TODOリストのコンポーネント)
<script setup>
import { ref, onMounted } from 'vue';
const tasks = ref([]); // タスクの配列
const newTask = ref(''); // ユーザーが入力するタスク
// ページロード時にローカルストレージからデータを取得
onMounted(() => {
const savedTasks = localStorage.getItem('tasks');
if (savedTasks) {
tasks.value = JSON.parse(savedTasks);
}
});
// タスクを追加
const addTask = () => {
if (newTask.value.trim() === '') return; // 空白チェック
tasks.value.push(newTask.value); // タスク追加
localStorage.setItem('tasks', JSON.stringify(tasks.value)); // localStorage に保存
newTask.value = ''; // 入力フィールドをクリア
};
// タスクを削除
const removeTask = (index) => {
tasks.value.splice(index, 1); // 指定したタスクを削除
localStorage.setItem('tasks', JSON.stringify(tasks.value)); // localStorage を更新
};
</script>
<template>
<div class="todo-container">
<h2>TODOリスト</h2>
<div class="todo-input">
<input v-model="newTask" placeholder="新しいタスクを入力" />
<button @click="addTask">追加</button>
</div>
<ul>
<li v-for="(task, index) in tasks" :key="index">
{{ task }}
<button @click="removeTask(index)">削除</button>
</li>
</ul>
</div>
</template>
<style scoped>
.todo-container {
max-width: 400px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.todo-input {
display: flex;
gap: 10px;
}
input {
flex: 1;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 8px 12px;
background: #28a745;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #218838;
}
ul {
list-style: none;
padding: 0;
}
li {
display: flex;
justify-content: space-between;
padding: 8px;
background: white;
margin: 5px 0;
border-radius: 4px;
}
li button {
background: #dc3545;
}
li button:hover {
background: #c82333;
}
</style>
onMounted() で localStorage からデータを取得
onMounted(() => {
const savedTasks = localStorage.getItem('tasks');
if (savedTasks) {
tasks.value = JSON.parse(savedTasks);
}
});
localStorage.getItem('tasks')
で保存されたタスクを取得JSON.parse()
を使ってオブジェクトに変換し、tasks.value
に格納
タスクを追加する処理
const addTask = () => {
if (newTask.value.trim() === '') return; // 空白チェック
tasks.value.push(newTask.value); // タスク追加
localStorage.setItem('tasks', JSON.stringify(tasks.value)); // localStorage に保存
newTask.value = ''; // 入力フィールドをクリア
};
newTask.value
をリストに追加- localStorage にデータを保存
- 入力欄をクリア
タスクを削除する処理
const removeTask = (index) => {
tasks.value.splice(index, 1); // 指定したタスクを削除
localStorage.setItem('tasks', JSON.stringify(tasks.value)); // localStorage を更新
};
- splice() を使って
tasks.value
のindex
番目の要素を削除 - 削除後に localStorage を更新
API を使った天気予報アプリの作成
外部 API(OpenWeather API)を利用して、ユーザーが入力した都市の天気情報を取得・表示するアプリを作成します。
プロジェクトディレクトリ
weather-app/
│── src/
│ ├── components/
│ │ ├── Weather.vue ← 天気情報のコンポーネント
│ ├── App.vue ← メインレイアウト
│ ├── main.js ← Vue インスタンスの作成
│── package.json
│── vite.config.js (または vue.config.js)
│── index.html
APIキーの取得
天気の情報を取得できるようにするためにOpen Weather MapからAPIキーを取得します。
Current weather and forecast - OpenWeatherMap
OpenWeather provides comprehensive weather data services, including current, forecast, and historicalweather information...
- ヘッダーのサインインをクリックします。

- Create an Accountをクリックします。

- 必要情報を入力し、アカウントを作成します。
- メールを開きメール認証を完了させます。

- ホーム画面から、ヘッダーの「アカウント」→「My API Keys」を選択します。

- APIキーをコピーします。

天気予報アプリの詳細な実装
完成する機能
- ユーザーが入力した都市の天気情報を取得
ref()
を使ってリアクティブなデータを管理- 取得したデータを Vue のテンプレートに表示
App.vue(メインレイアウト)
<script setup>
import Weather from './components/Weather.vue';
</script>
<template>
<div>
<h1>天気予報アプリ</h1>
<Weather />
</div>
</template>
Weather.vue(天気情報のコンポーネント)
- YOUR_API_KEYに先ほど取得したAPI KEYを入力します。
これは秘匿情報なので、Gitなど公開しないでください。
<script setup>
import { ref } from 'vue';
import axios from 'axios';
const city = ref('');
const weather = ref(null);
const errorMessage = ref('');
const apiKey = 'YOUR_API_KEY';
// 天気データ取得用関数
const fetchWeather = async () => {
if (!city.value.trim()) {
errorMessage.value = '都市名を入力してください';
return;
}
try {
const response = await axios.get(
`https://api.openweathermap.org/data/2.5/weather?q=${encodeURIComponent(city.value)}&appid=${apiKey}&units=metric&lang=ja`
);
weather.value = response.data;
errorMessage.value = '';
} catch (error) {
errorMessage.value = '天気情報の取得に失敗しました。都市名を確認してください。';
}
};
</script>
<template>
<div class="weather-container">
<h2>天気予報</h2>
<div class="input-container">
<input v-model="city" placeholder="都市名を入力" />
<button @click="fetchWeather">検索</button>
</div>
<p v-if="errorMessage" class="error">{{ errorMessage }}</p>
<div v-if="weather" class="weather-info">
<h3>{{ weather.name }} の天気</h3>
<p>気温: {{ weather.main.temp }}℃</p>
<p>天気: {{ weather.weather[0].description }}</p>
</div>
</div>
</template>
<style scoped>
.weather-container {
max-width: 400px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.input-container {
display: flex;
gap: 10px;
}
input {
flex: 1;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 8px 12px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
.error {
color: red;
margin-top: 10px;
}
.weather-info {
margin-top: 20px;
padding: 10px;
background: #fff;
border-radius: 4px;
}
</style>
コードの解説
- 都市名を入力し、検索ボタンを押すと天気情報を取得
- API 取得が成功すれば
weather
にデータを格納し、画面に表示 - エラー発生時は
errorMessage
にエラーメッセージを表示 v-model
を使い、リアルタイムに入力を反映axios.get()
を使って OpenWeather API からデータ取得- 都市名が空の場合や API 取得に失敗した場合にエラーメッセージを表示
フォームバリデーションの実装
ユーザーが入力した 名前・メール・パスワード をバリデーションし、正しいデータのみ送信できるようにします。
完成する機能
v-model
を使ってリアルタイムにフォーム入力を反映- 必須チェック・メール形式チェック・パスワードの長さチェックを実装
App.vue(フォームバリデーションの実装)
<script setup>
import { ref } from 'vue';
const name = ref('');
const email = ref('');
const password = ref('');
const errors = ref([]);
const validateForm = () => {
errors.value = [];
if (!name.value.trim()) {
errors.value.push('名前を入力してください');
}
if (!email.value.trim()) {
errors.value.push('メールアドレスを入力してください');
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value)) {
errors.value.push('正しいメールアドレスを入力してください');
}
if (!password.value.trim()) {
errors.value.push('パスワードを入力してください');
} else if (password.value.length < 6) {
errors.value.push('パスワードは6文字以上で入力してください');
}
};
</script>
<template>
<div class="form-container">
<h2>ユーザー登録</h2>
<div class="input-group">
<input v-model="name" placeholder="名前" />
<input v-model="email" placeholder="メールアドレス" />
<input type="password" v-model="password" placeholder="パスワード" />
</div>
<button @click="validateForm">登録</button>
<ul v-if="errors.length" class="error-list">
<li v-for="error in errors" :key="error">{{ error }}</li>
</ul>
</div>
</template>
<style scoped>
.form-container {
max-width: 400px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.input-group {
display: flex;
flex-direction: column;
gap: 10px;
}
input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 8px 12px;
background: #28a745;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #218838;
}
.error-list {
color: red;
margin-top: 10px;
}
</style>
コードの解説
errors.value
にエラーリストを格納し、バリデーション結果を表示- メールアドレスの形式チェックは正規表現 (
/^[^\s@]+@[^\s@]+\.[^\s@]+$/
) を使用 password.value.length < 6
でパスワードの長さをチェック- エラーがある場合、リストとして画面に表示
- バリデーションが通らないと登録ボタンを押しても処理が進まない
Vue.js アプリ開発の次のステップ
ここまでで Vue の基本を学びましたが、さらにレベルアップするために 次のステップ に進みましょう!
Vue Router を使ってアプリを複数ページ化する

Vue 3 の Vue Router を初心者向けに解説!【SPA開発の基礎】
Vue 3の公式ルーティングライブラリ「Vue Router」の基本を解説!SPAの仕組み、ページ遷移の実装、動的ルートの活用方法を詳しく紹介します。
Pinia を使ってデータを一元管理する

Vue 3 の状態管理ライブラリ「Pinia」を初心者向けに解説!
Vue 3の状態管理ライブラリ「Pinia」の基本を初心者向けに解説!インストール方法からstate・actions・gettersの使い方、実践例まで詳しく紹介します。
まとめ
- Vue 3 を使ったアプリ開発の流れを学んだ
- TODOリスト、天気予報アプリ、フォームバリデーションを実装した
- 次のステップとして Vue Router や Pinia に挑戦
Vue での開発を楽しみながら、どんどんアプリを作っていきましょう!
コメント