カテゴリー: FrontEnd

Vue.js入門その3〜簡単にTODOアプリを作ってみたよ〜

はじめに

7/12 修正
記事下部にて、filterメソッドを使用している箇所がありましたが、forEachの方が適しているとご指摘がありましたので、修正しました。

以前Qiitaの方に投稿した記事ですが、こちらにも投稿します。
少しご指摘もいただいたので、FIX版になります!
Vue.jsの勉強で超簡単なタスク管理アプリを作ってみる

今まで、Vue.jsの記事として下記を投稿してきました。

ただ、今ひとつピンとこなかったため、よくあるTODOアプリを作成してみました。

サンプルはこちらです。
https://jsfiddle.net/naoki85/fo26rmr0/12/

準備

Bootstrapを読み込み

CSSは面倒なので、Bootstrapを使用したいと思います。
JS Fiddleでは、External Resourcesにて読み込むことができます。
CDNのURLを取得し、JS Fiddleの左側、External Resourcesに入力しておきます。

このとき、BootstrapのJSはJQueryを必要とするのでCSSのみにしておきます。
(後でコンソールでエラーが出てしまうので。。。)

HTMLで目的のかたちを作る

<table class="table table-striped">
  <thead>
    <tr>
      <th>Name</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Studying JavaScript</td>
      <td>
        <div class="btn btn-danger">Done!</div>
      </td>
    </tr>
    <tr>
      <td>Studying PHP</td>
      <td>
        <div class="btn btn-danger">Done!</div>
      </td>
    </tr>
    <tr>
      <td>Studying Ruby</td>
      <td>
        <div class="btn btn-danger">Done!</div>
      </td>
    </tr>
    <tr>
      <td><input class="form-control"></td>
      <td>
        <div class="btn btn-default">Create Task</div>
      </td>
    </tr>
  </tbody>
</table>

このような感じです。

タスクの一覧表示

Vueインスタンスの作成

var vm = new Vue({
  el: '#tasks-index',
  data: {
    tasks: [
      { id: 1, name: 'Studying JavaScript', isDeleted: false },
      { id: 2, name: 'Studying PHP',        isDeleted: false },
      { id: 3, name: 'Studying Ruby',       isDeleted: false },
    ]
  }
})

後述しますが、TODOの完了は論理削除としますので、プロパティにisDeletedをもたせておきます。

v-forとv-ifを使用して条件ループ

まずはテーブルタグの方にid="tasks-index"を割り当てておきます。

また、v-fortasksの値をループ処理します。
そして、v-ifで、isDeleted = trueの値だけ出力するようにします。

<table id="tasks-index" class="table table-striped">
  <thead>
    <tr>
      <th>Name</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="task in tasks">
    <td>{{ task.name }}</td>
      <td>
        <div class="btn btn-danger">Done!</div>
      </td>
    </tr>
    <tr>
      <td><input class="form-control"></td>
      <td>
        <div class="btn btn-default">Create Task</div>
      </td>
    </tr>
  </tbody>
</table>

これで、一覧表示はできましたので、次は新規登録です!

タスクの新規登録

クリックイベントの設定

「Create Task」ボタンが押されたら、tasksプロパティに値を追加したいので、クリックイベントを設定します。
v-on:clickを使用すれば、設定したインスタンスメソッドにとばすことができます。

今回は後ほど、createTaskというメソッドを作りたいと思います。

<!-- 省略 -->
    <tr>
      <td><input v-model="newTask" class="form-control"></td>
      <td>
        <div class="btn btn-default" v-on:click="createTask">Create Task</div>
      </td>
    </tr>
  </tbody>
</table>

また、入力フォームとしてinputタグを使用していますが、そこにv-modelnewTaskというプロパティをバインディングしています。
新規登録に際し、新しい値をどこかに保持する必要があると考えたのですが、とりあえず新しいインスタンスプロパティを用意し、そこに保持する方法としました。
(このあたりはもっとスマートな方法がありそうです。。。)

インスタンスに追記

var vm = new Vue({
  el: '#tasks-index',
  data: {
  tasks: [
    { id: 1, name: 'Studying JavaScript', isDeleted: false },
    { id: 2, name: 'Studying PHP',        isDeleted: false },
    { id: 3, name: 'Studying Ruby',       isDeleted: false },
  ],
  newTask: '',
  },
  methods: {
    createTask: function (event) {
      // 新しいIDを、配列の最後のIDから計算
      var new_id = this.tasks[this.tasks.length - 1].id + 1;
      // 配列に追加
      this.tasks.push({ id: new_id, name: this.newTask, isDeleted: false });
      // プロパティを空に戻す
      this.newTask = '';
    }
  }
})

タスクの完了(論理削除)

前述したように、タスクの完了とは、論理削除とさせていただきます。

クリックイベントの設定

<div class="btn btn-danger" v-on:click="doneTask(task.id)">Done!</div>

doneTaskメソッドをVueインスタンスに追記したいと思います。

メソッドの追記

var vm = new Vue({

  // 中略

  methods: {

    // 中略

    doneTask: function (task_id) {
      this.tasks.filter(function (task) {
        if (task.id === task_id) {
          return task.isDeleted = true;
        }
      })
    }
  }
})

doneTaskメソッドは、引数としてtask_idを受け取ります。
その後、tasksプロパティをfilterで処理し、対象のIDのisDeletedをtrueにして完了(論理削除)とします。

filterではなくforEachを使用

7/12 追記

filterメソッドはブロック内を満たす新しい配列を生成するため、今回のように論理削除する場合にはforEachの方が適しているというご指摘をいただきました。
そのため、doneTaskメソッドは下記のように修正しました。

    doneTask: function (task_id) {
-     this.tasks.filter(function (task) {
+     this.tasks.forEach(function (task) {
        if (task.id === task_id) {
          return task.isDeleted = true;
        }
      })
    }

さいごに

簡単ではありますが、勉強用に作成してみました。

まだ公式リファレンスが残っているので、もう少し基本をやり、近いうちにSPAを作って公開したいと思います!

naoki85

シェア
執筆者:
naoki85
タグ: JavaScriptVuejs

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

2週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

4週間 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前