はじめに
これまでの記事で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 での開発を楽しみながら、どんどんアプリを作っていきましょう!
  
  
  
  

コメント