はじめに
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から影響を受けています。
らしい。
状態管理に関わる概念を定義、分離し、特定のルールを敷くことで、コードの構造と保守性を向上させることができます。
メリットとのこと。
単一方向のデータフローで、グローバルシングルトンにすることでコンポーネント間のデータの受け渡しを取っ払うそうです。
ソースコード解説
今回は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の返却値による状態の更新)のためにアクションが存在するらしい。
なるほど。