LoginSignup
24
21

More than 5 years have passed since last update.

Vue.jsとVuexでTodoListを作ってみた

Last updated at Posted at 2017-09-04

はじめに

Vue.jsとVuexでTodoListを作ってみたので備忘録として書いていきます。

Vuexはまだ理解が浅いので間違っていたらすみません。

成果物

※一瞬見えてはいけない何かが見えるのはご愛嬌・・・

v-cloakというVueの機能で非表示にできました!ありがとうございます!(2017/9/10追記)

機能は「追加」と、「完了」と、「完了から戻す」3つだけ。

次の記事 Vue.jsとVuexとwebpackでTodoListを作ってみた

さらに次の記事 Vue.jsとVuexとwebpackで単一ファイルコンポーネント化してTodoListを作ってみた

スペック

  • JSは割とよく書く
  • JSフレームワークはVue.jsを少しだけ
    • 大規模に使ったことはない
  • Fluxは使ったこと無い

Vue.js

公式

少しだけ使ったことあるJSフレームワーク。

HTMLとJSとCSSの知識はあるのでなんとか書ける。

Vuex

公式

Vuex は Vue.js アプリケーションのための 状態管理パターン + ライブラリです。

とのこと。

Flux、 Redux そして The Elm Architectureから影響を受けています。

らしい。

状態管理に関わる概念を定義、分離し、特定のルールを敷くことで、コードの構造と保守性を向上させることができます。

メリットとのこと。

vuex.png

単一方向のデータフローで、グローバルシングルトンにすることでコンポーネント間のデータの受け渡しを取っ払うそうです。

ソースコード解説

全体

今回は1つのHTMLに書いていて、コンポーネント化など全くしていません・・・

※ソースコードは抜粋しています

State

Todo ListとDone Listを定義。

var store = new Vuex.Store({
  state: {
    todos: [],
    dones: []
  },
});

Vue Components

ディスパッチの記述をstoreからthis.$storeに変更しました!コメントありがとうございます!(2017/9/11追記)

Todo Input

入力された中身を受け取って、追加アクションをディスパッチ。

<div class="wrap">
  <h2>Todo Input</h2>
  <input type="text" @keyup.enter="addTodoText"/>
</div>
addTodoText: function(e){
  var text = e.target.value;
  this.$store.dispatch('addTodo', {
    text: text
  });
  e.target.value = '';
}

Todo List

Todo Listの表示、完了アクションをディスパッチ。

<div class="wrap">
  <h2>Todo List</h2>
  <ul>
    <li v-for="todo in todos">
      <p>ID : {{todo.id}}</p>
      <p>Text : {{todo.text}}</p>
      <button @click="doneTodo(todo.id)">Done</button>
    </li>
  </ul>
</div>
doneTodo: function(id) {
  this.$store.dispatch('done', {
    id: id
  })
}

Done List

Done Listの表示、完了から戻すアクションをディスパッチ。

<div class="wrap">
  <h2>Done</h2>
  <ul>
    <li v-for="done in dones">
      <p>ID : {{done.id}}</p>
      <p>Text : {{done.text}}</p>
      <button @click="resetTodo(done.id)">Reset</button>
    </li>
  </ul>
</div>
resetTodo: function(id) {
  this.$store.dispatch('reset', {
    id: id
  })
}

Actions

それぞれ、ミューテーションをコミットする。

actions: {
  addTodo (context, todo) {
    context.commit('ADD_TODO',todo.text);
  },
  done (context, todo) {
    context.commit('DONE_TODO',todo.id);
  },
  reset (context, todo) {
    context.commit('RESET_TODO',todo.id);
  }
}

Mutations

ステートを変化させる。

Todo ListとDone Listに追加と削除をするだけ。

mutations: {
  ADD_TODO (state, text) {
    var todo = {
      id: 0,
      text: text
    }
    if (state.todos.length !== 0) {
      todo.id = state.todos[state.todos.length -1].id + 1;
    }
    state.todos.push(todo);
  },
  DONE_TODO (state, id) {
    for (var i = 0; i < state.todos.length; i++) {
      if (state.todos[i].id === id) {
        state.dones.push(state.todos[i]);
        state.todos.splice(i, 1);
        break;
      }
    }
  },
  RESET_TODO (state, id) {
    var todo = {};
    for (var i = 0; i < state.dones.length; i++) {
      if (state.dones[i].id === id) {
        todo = state.dones[i];
        state.dones.splice(i, 1);
        break;
      }
    }
    state.todos.push(todo);
    state.todos.sort(function(a,b){
      if(a.id<b.id) return -1;
      if(a.id > b.id) return 1;
      return 0;
    })
  }
}

所感

ファイルを分割していけばどこに何が書かれているかわかりやすそう(今回は1つにまとめているが・・・)。

書きながらアクションの存在価値がわからなかったが、アクションは非同期処理が行えるのがメリットとのこと。

よくわからんと思いながら読んでいたら、ミューテーションは状態の変化をするため、必ず同期的に行うべしと書いてあり、非同期な処理による状態の更新(APIの返却値による状態の更新)のためにアクションが存在するらしい。

なるほど。

24
21
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
21