Mima Design MemottoWEB DESIGNER · mima

Vue.jsで作るシンプルな単語帳アプリ

単語と意味を登録して、あとから検索できる単語帳は、Vue.jsの基本を学ぶ題材に向いています。入力フォーム、配列データ、クリックイベント、条件分岐、ブラウザ保存という、フロントエンド開発で頻繁に使う機能を一つの小さなアプリにまとめられるためです。

今回は外部サーバーや複雑な環境構築を使わず、Vue.jsのCDN版で動く単語帳を作ります。HTMLファイルを開くだけで試せる構成にして、学習用のサンプルから少しずつ実用的な機能へ発展させます。

作る機能と画面を決める

最初から多機能な暗記アプリを目指すと、データ設計や画面構成で迷いやすくなります。今回は「単語を追加する」「一覧を見る」「キーワードで絞り込む」「削除する」「ブラウザに保存する」という五つに絞ります。

画面には、単語と意味を入力するフォーム、登録済みデータの一覧、検索欄を配置します。各単語は、単語そのもの、意味、登録日時を持つオブジェクトとして管理します。

実装前に決めておくと迷いにくい項目は次のとおりです。

  • 単語と意味はどちらも必須にする
  • 登録後は入力欄を空に戻す
  • 一覧には削除ボタンを付ける
  • データはブラウザのローカルストレージに保存する

データの流れも簡単に整理しておきます。入力値を配列へ追加し、配列を画面へ表示し、変更があったら保存するという流れです。

  • wordsで単語データを管理する
  • filteredWordsで検索結果を作る
  • addWordで新しい単語を登録する
  • removeWordで指定した単語を削除する

Vue.jsを読み込んで土台を作る

まずindex.htmlを作り、Vue.jsをCDNから読み込みます。ビルドツールを使わないため、Vueの学習を始めたばかりでもコードの変化を確認しやすい構成です。

<div id="app">
  <h1>単語帳</h1>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="app.js"></script>

app.jsでは、Vue.createApp()でアプリケーションを作成し、最後にmount('#app')を呼び出します。これで、id="app"を持つ要素がVueの管理対象になります。

const { createApp } = Vue;

createApp({
  data() {
    return {
      words: [],
      newWord: '',
      newMeaning: '',
      keyword: ''
    };
  }
}).mount('#app');

単語データを画面に表示する

フォームと一覧をHTMLへ追加します。v-modelを使うと、入力欄の値とデータを自動的に同期できます。ボタンのクリックには@click、フォーム送信には@submit.preventを使います。

<form @submit.prevent="addWord">
  <input v-model.trim="newWord" placeholder="英単語">
  <input v-model.trim="newMeaning" placeholder="意味">
  <button>登録</button>
</form>

<ul>
  <li v-for="item in filteredWords" :key="item.id">
    <strong>{{ item.word }}</strong>
    <span>{{ item.meaning }}</span>
    <button @click="removeWord(item.id)">削除</button>
  </li>
</ul>

v-forは配列の要素を繰り返し表示するディレクティブです。keyに一意なIDを指定しておくと、Vueが各要素を正しく追跡できます。単語がまだ登録されていない場合は、v-ifでメッセージを表示すると親切です。

登録と削除の処理を追加する

登録処理では、入力欄が空のまま送信された場合に何もしないようにします。問題がなければ、id、単語、意味を持つオブジェクトをwordsへ追加します。

methods: {
  addWord() {
    if (!this.newWord || !this.newMeaning) return;

    this.words.push({
      id: Date.now(),
      word: this.newWord,
      meaning: this.newMeaning
    });

    this.newWord = '';
    this.newMeaning = '';
    this.saveWords();
  },

  removeWord(id) {
    this.words = this.words.filter(item => item.id !== id);
    this.saveWords();
  }
}

filter()は条件に合う要素だけを残した新しい配列を返します。そのため、削除対象以外のデータでwordsを置き換えられます。登録後と削除後に保存処理を呼ぶことで、画面を再読み込みしてもデータを維持できます。

検索と絞り込みを実装する

検索欄を追加し、入力された文字に一致する単語だけを表示します。表示用の配列にはcomputedを使います。元のwordsを直接変更せず、検索キーワードが変わるたびに結果を計算できる点が特徴です。

<input v-model.trim="keyword" placeholder="単語や意味を検索">
computed: {
  filteredWords() {
    const key = this.keyword.toLowerCase();

    return this.words.filter(item =>
      item.word.toLowerCase().includes(key) ||
      item.meaning.toLowerCase().includes(key)
    );
  }
}

英単語だけでなく意味も検索対象にすると、復習したいテーマから探せます。日本語の意味を中心に入力する場合は、文字列の前後にある空白を削除しておくと、意図しない検索結果を減らせます。

ローカルストレージへ保存する

localStorageは、ブラウザ内に文字列を保存できる仕組みです。配列やオブジェクトはそのまま保存できないため、JSON.stringify()で文字列に変換し、読み出すときはJSON.parse()で戻します。

methods: {
  saveWords() {
    localStorage.setItem('vue-words', JSON.stringify(this.words));
  },

  loadWords() {
    const saved = localStorage.getItem('vue-words');
    if (saved) {
      this.words = JSON.parse(saved);
    }
  }
},

mounted() {
  this.loadWords();
}

mounted()はVueの画面が準備されたあとに実行されます。ここで保存済みデータを読み込めば、アプリを開いた直後から以前の単語が一覧に表示されます。データを消去する機能を加える場合は、確認ダイアログを表示してからlocalStorage.removeItem()を実行します。

スマートフォンで使いやすく整える

単語帳はスマートフォンで使う機会が多いため、入力欄やボタンを指で押しやすい大きさにします。カード形式の一覧、十分な行間、意味を隠して確認できる表示を加えると、学習アプリらしさが高まります。普段の端末やアプリに関する記録は、スマートフォン記事も画面設計の参考になります。

文字の印象も使いやすさに影響します。見出しと本文のサイズ差を付け、単語は太字、意味は落ち着いた色にすると視線の移動が自然です。日本語と英語を混在させる場合は、Webフォントの選び方を確認しながら読みやすい書体を選びます。

実機で確認すると、パソコンでは見つけにくい問題に気付けます。古い端末を含めた表示確認には、iPhone 5sの購入記録のような端末選びの視点も役立ちます。画面幅、ボタンの押しやすさ、キーボード表示時のレイアウトを確認してください。

この単語帳に、正解・不正解の記録、ランダム出題、カテゴリー分類などを加えると、Vue.jsの状態管理をさらに実践できます。まずは一つのHTMLファイルで動作を完成させ、必要になった段階でコンポーネントやViteへ移行すると、仕組みを理解しながら開発を進められます。

完成したコードをブラウザで動かし、好きな単語を数件登録して検索と保存を試してみてください。小さな機能を一つずつ追加しながら、自分の学習方法に合う単語帳へ育てていきましょう。