Vue.js入門|60行で簡単作成!!最小構成のTODOアプリケーションを作成しよう

初めに

Vue.js を学んでみたはいいものの何を作ったらいいかわからない初心者向けに TODO アプリの作り方を解説しようと思います。

今から解説するのは、シンプルな TODO アプリケーションの作成例です。
アプリケーションは、ユーザーが TODO 項目を追加、編集、削除し、ブラウザの Web Storage に TODO リストを保存する機能も追加するようにします。以下が完成した TODO アプリケーションです。

早速全体のソースコードを見てみましょう。

<html>
  <head>
    <title>TODO</title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <div id="app">
    <form @submit.prevent="addTodo">
      <input v-model="newTodo" placeholder="TODO追加" />
      <button type="submit">追加</button>
    </form>
    <ul>
      <li v-for="todo in todos" :key="todo.id">
        <input type="checkbox" v-model="todo.completed" />
        <span v-if="!todo.editing">{{ todo.text }}</span>
        <input
          v-else
          v-model="todo.text"
          @blur="todo.editing = false"
          @keyup.enter="todo.editing = false"
        />
        <button @click="removeTodo(todo)">削除</button>
        <button v-if="!todo.editing" @click="todo.editing = true">編集</button>
      </li>
    </ul>
    <button @click="saveTodos">保存</button>
  </div>
</html>

<script>
  const { createApp } = Vue;
  createApp({
    data() {
      return {
        newTodo: "",
        todos: JSON.parse(localStorage.getItem("todos")) || \[\],
      };
    },
    methods: {
      addTodo() {
        let text = this.newTodo.trim();
        if (text) {
          this.todos.push({
            id: this.todos.length + 1,
            text,
            completed: false,
          });
          this.newTodo = "";
        }
      },
      removeTodo(todo) {
        this.todos = this.todos.filter((t) => t.id !== todo.id);
      },
      saveTodos() {
        localStorage.setItem("todos", JSON.stringify(this.todos));
      },
    },
  }).mount("#app");
</script>

CDN から Vue.js をダウンロードする

<head>
  <title>TODO</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>

以上のソースコードは CDN から Vue.js を読み込みます。

Vue.js にはいくつか環境構築の方法がありますが、 大規模プロジェクトになると、
CLI でプロジェクトテンプレートを作成して作ったほうがいいです。

ですが、今回は小規模のアプリケーションなので CDN を利用します。

TODO を追加する機能を作成する

 <form @submit.prevent="addTodo">
   <input v-model="newTodo" placeholder="TODO追加" />
   <button type="submit">追加</button>
 </form>

<form>要素には@submit.preventディレクティブが付いた submit イベントリスナーを作成します。
フォームが送信されるとデフォルトの動作を防止し、addTodo()メソッドを呼び出します。
submitpreventを追加しないと、リダイレクト処理が発生してしまうので忘れずにつけます。

フォームには、v-model ディレクティブを持つ input 要素があり、新しい TODO 項目を入力するために使用されます。

addTodo() {
  let text = this.newTodo.trim();
  if (text) {
    this.todos.push({
      id: this.todos.length + 1,
      text,
      completed: false,
  });
  this.newTodo = "";
  }
}

このメソッドは、フォームから入力された新しい TODO を追加するための関数です。

初めの変数textに、newTodoの値をトリミングした値を代入します。
条件分岐を使用してtextが空でない場合に、todos配列に新しい TODO を追加します。

新しい TODO は、idtextcompletedのプロパティを持ちます。
idは、現在のtodos配列の長さ+1 になります
textは、入力された新しい TODO のテキスト
completedは初期値は False で、TODO を完了したがユーザーがチェックする項目です。

最後に、newTodoの値を空にします。

TODO をリスト表示する

<ul>
  <li v-for="todo in todos" :key="todo.id">
    <input type="checkbox" v-model="todo.completed" />
    <span v-if="!todo.editing">{{ todo.text }}</span>
    <input
      v-else
      v-model="todo.text"
      @blur="todo.editing = false"
      @keyup.enter="todo.editing = false"
    />
    <button @click="removeTodo(todo)">削除</button>
    <button v-if="!todo.editing" @click="todo.editing = true">編集</button>
  </li>
</ul>

v-forディレクティブを使用して、TODO リストのすべての要素に対してli要素を生成します。
それぞれの li 要素には、v-modelディレクティブを持つチェックボックスがあり、TODO 項目が完了したかどうかを確認できます。
また、span要素には、TODO 項目のテキストが表示され、削除ボタンを押すことで TODO 項目を削除できます。

さらに、編集ボタンを押すことで、TODO 項目を編集でき、
@blur イベントリスナーを使用して、 フォームから外れるかと編集が実行されます。
同様に @keyup.enterイベントリスナーを使用して、Enter キーを押すと、編集が実行されます。

removeTodo(todo) {
  this.todos = this.todos.filter((t) => t.id !== todo.id);
},

TODO 項目を削除するための関数です。

引数として渡されたtodoオブジェクトが持つidプロパティがtodos配列のそれぞれの要素の id プロパティと一致しない要素だけを含む新しい配列を生成し、this.todosに代入しています。
これにより、指定した TODO 項目が削除され、表示も更新されます。

保存機能の作成

localStorage.setItem("todos", JSON.stringify(this.todos));

TODO リストを Web Storage に保存するための記述です。
localStorage.setItem()メソッドは、Web Storage にデータを保存するために使用されます。
第一引数には、データを保存するためのキー名、第二引数には、保存するデータを渡します。
この TODO アプリでは、“todos"という名前のキーで、現在のtodos配列を JSON 形式に変換したものを保存しています。

data() {
  return {
    newTodo: "",
    todos: JSON.parse(localStorage.getItem("todos")) || \[\],
  };
},

保存されたデータは、次回アプリを開くときに読み込まれ、TODO リストが復元されます。

終わり

いかがでしょうか。
非常にシンプルにできているかと思います。

もし疑問点等がありましたら、お気軽にお問合せください。

なお今回作成した、ソースコードは以下に置きます。
https://github.com/wiblok/Vue.js