Vue.jsロゴ

[Vue.js]TODOアプリの開発〜タスクのリスト表示 / 完了・未完了の処理 / リストのスタイル整形 / タスクの削除

投稿日:

カテゴリー:

この記事はUdemyの講座「Vue JS入門決定版!jQueryを使わないWeb開発 – 導入からアプリケーション開発まで体系的に動画で学ぶ」の学習を進めながら書いた記事になります。Vue.jsに関する記事の一覧はこちらからご覧いただけます。

引き続き、Vue.jsによるTODOアプリの開発を上記レクチャー動画を見ながら進めていきたいと思います。

リスト表示

今まで、inputから入力してAddボタンを押したものを配列に格納するという処理を作ってきました。

ここからは、その配列に格納したデータをリスト表示させる部分を作っていきたいと思います。v-forディレクティブを利用します。

https://jp.vuejs.org/v2/guide/list.html#v-for-%E3%81%A7%E9%85%8D%E5%88%97%E3%81%AB%E8%A6%81%E7%B4%A0%E3%82%92%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B
ここら辺も参考になるかも
<div id="app">
  <h2>Todo List</h2>
  <form v-on:submit.prevent>
    <input type="text" v-model="newItem">
    <button v-on:click="addItem">
      Add
    </button>
  </form>
<!-- ここから追記スタート -->
  <ul>
    <li v-for="todo in todos">
      <span>{{ todo.item }}</span>
    </li>
  </ul>
<!-- ここまで -->
  <pre>{{ $data }}</pre>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

ulタグの中にliタグを1つ作り、そのliタグに<li v-for="todo in todos">というようにv-forディレクティブを記述します。

そして、liタグの中にspan要素を作り、マスタッシュ構文でタスク名を表示させます。こんな感じですね。

<span>{{ todo.item }}</span>

これでデモを行ってみましょう。

タスクの完了・未完了の管理

タスクの完了と未完了を管理できるように、機能追加実装を行います。

まず、それぞれのタスクにチェックボックスを設置します。

<div id="app">
  <h2>Todo List</h2>
  <form v-on:submit.prevent>
    <input type="text" v-model="newItem">
    <button v-on:click="addItem">
      Add
    </button>
  </form>
  <ul>
    <li v-for="todo in todos">
      <input type="checkbox"><!-- ←追記部分 -->
      <span>{{ todo.item }}</span>
    </li>
  </ul>
  <pre>{{ $data }}</pre>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

次に、オブジェクトtodoにタスクの完了・未完了を管理する部分を追加する。

var app = new Vue({
	el: "#app",
  data: {
  	newItem: '',
    todos: []
  },
  methods: {
    addItem: function() {
      // alert();
      if( this.newItem == '' ) return;
      var todo = {
      	item: this.newItem,
        isDone: false //←追記
      };

      this.todos.push(todo);
      this.newItem = '';
    }
  }
})

isDonefalseの場合は作業か完了していない、trueの場合にはタスクが完了している、と判断します。

次はv-modelディレクティブを使って、先ほど設置したチェックボックスとisDoneを双方向データバインディングします。テンプレート側(HTML側)の<input>タグにv-modelを追記していきます。

<input type="checkbox" v-model="todo.isDone">

こうすることによって、チェックボックスとidDoneと東方紅データバインディングすることができます。下はこの結果のデモです。

https://jp.vuejs.org/v2/guide/forms.html
こちらの公式チュートリアルも参考になります

スタイルでリストを整形する

リストのスタイルを設定していきます。まずは、リストの頭に付いている「・」を表示させないようにしましょう。jsFiddleのCSS欄に記述していきます。

#app ul {
  list-style: none;
}

これで表示されなくなります。

次は動的な部分なんですが、チェックを入れた=タスクが完了となります。ですので、チェックを入れた際にテキストに横線を入れる設定を行います。

v-bind:classを使います。

<span v-bind:class="{ done: todo.isDone }">{{ todo.item }}</span>

span要素にこのように追記します。todo.isDonetrueの場合にdoneというクラスを表示する、という内容になります。ですので、todo.isDonefalse(デフォルト値)の場合にはクラスは出力されません。

https://jp.vuejs.org/v2/guide/class-and-style.html#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%A7%8B%E6%96%87
こちらが参考になります

そして、class="done"が出力された際のスタイルを追記します。

#app li > span.done {
  text-decoration: line-through;
}

動作をDOMの動きも併せて確認しましょう。

タスクの削除

登録したタスクを1件ずつ削除する機能を実装します。今のままでは登録はできて完了処理もできるけど、削除ができないのも変ですもんね。

まず、タスク名の右側に削除ボタンを設置します。(ulタグの中だけ記載)

<ul>
    <li v-for="todo in todos">
        <input type="checkbox" v-model="todo.isDone">
        <span v-bind:class="{ done: todo.isDone }">{{ todo.item }}</span>
        <button>Delete</button>
    </li>
</ul>

これでタスク名の右側にDeleteボタンが追加されました。

次に、ボタンにv-on:clickを設定します。イベントハンドラ名はdeleteItemとしておきます。

<button v-on:click="deleteItem">Delete</button>

イベントハンドラを設定していきましょう。

methodsの中、addItemメソッドの次に記述していきましょう。

var app = new Vue({
	el: "#app",
  data: {
  	newItem: '',
    todos: []
  },
  methods: {
    addItem: function() {
      // alert();
      if( this.newItem == '' ) return;
      var todo = {
      	item: this.newItem,
        isDone: false
      };

      this.todos.push(todo);
      this.newItem = '';
    },
    deleteItem: function() { //←とりあえず動くかどうかテストのためにアラートを表示させている
    	alert();
    }
  }
})

動作確認をしてみてくださいね。

削除ボタンはタスクの数だけ存在するようになります。ですので、どのボタンに対して動作させるのかを判断させなければなりません。

そのために、deleteItemメソッドの引数に配列todosindexを渡すようにします。

deleteItem: function(index) {
    alert();
}

テンプレート側でも記述が必要になります。

削除ボタンのクリックイベントでdeleteItemメソッドを呼ぶ時に配列のindexを渡すようにします。

<button v-on:click="deleteItem(index)">Delete</button>

このdeleteItem(index)indexがどこで取れるのかというと、<li v-for="todo in todos">部分になります。ですのでこの部分を、

<li v-for="(todo, index) in todos">

とします。第一引数(todo)はValue、第二引数(index)はKeyが取得できます。

https://jp.vuejs.org/v2/guide/list.html#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE-v-for

alert(index)としてテストしてみましょう。タスクの上から順番に、0、1、2…という順番でキーを取得できていることが確認できます。

そして、spliceを使って配列のデータを削除させます。

deleteItem: function(index) {
    // alert(index);
    this.todos.splice(index, 1)
}

第一引数(index)が削除を始める配列のインデックス、第二引数(この場合1)は削除をする個数となります。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
https://jp.vuejs.org/v2/guide/migration.html#Array-prototype-remove-%E5%89%8A%E9%99%A4
こちらにもVueでspliceの使い方の例が掲載されています。

実際に動かしてみるとこのようになります。

これでTodoアプリの完成となります。

まとめ

ここまでで一通りのTODOアプリの作成は終了となります。これで基本的なVue.jsの扱い方が少し理解できたのかな?という感覚です。

まだまだ基礎の基礎なので、奥の深さを感じますがさすが導入コストが低いだけあって、スムーズに学習を始められましたし、手軽に試すことができて楽しいですね。

今後も学習を続けていきたいと思います。

Vue.js以外にも基本的なWebスキルを動画で受講することができます。年に何回かセールがあるので、その時にまとめて購入するのがおすすめです。

Gifu WordPress Meetup の
運営・開催に協力しています。

WordPress Meetup とは、世界各国 100 以上の国々で 700 余りの グループが活動している WordPress コミュニティです。

オレインデザイン代表 久野晃司は、岐阜での WordPress Meetup の運営・開催に協力しています。

CoderDojo岐阜 の
運営・開催に協力しています。

CoderDojo とは 7〜17歳を対象とした非営利のプログラミング道場で、CoderDojo岐阜は岐阜県岐阜市にある みんなの森 ぎふメディアコスモス を拠点として毎月定期開催をしています。

オレインデザインは、CoderDojo岐阜へ寄付を行い、定期的かつ安定的な運営と開催に協力をしています。