まえがき
Vue.js用のFluxライクなライブラリVuexを試してみました。
注意:まだ開発中でAPIも変わる可能性があります(2015/12/25)
2017/12/17 追記
改めて学び直してみました。
データの流れ
詳しくはドキュメントを読んだ方が正確だけど、この図だけ見れば何となくやりたいことがわかるはず。
何となくFluxっぽいですね。
自分の理解としては
- コンポーネントからActionを呼び出してそこで外部のAPIと通信してデータを取得
- Mutationでデータをセット
- Stateがコンポーネントの数値をアップデート
という流れ(間違ってたらすみません)。
Vue.jsは値の取得に対しては関与しないフレームワークですが、Vuexを入れることにより値の取得からセットまでライブラリで制御できるので、無秩序になりがちだったVue.jsを使ったアプリケーションに秩序をもたらすことが出来そうです。
作った物
作った物はおなじみToDoList。横着して値の追加しか対応していません。
コードと解説
Vueifyを使ってコンパイルすることを前提としているので、.vueなる拡張子が出てくるので注意。
まずはstoreから
import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import mutations from './mutations'
Vue.use(Vuex);
const state = {
input: "",
todos: []
}
export default new Vuex.Store({
state,
actions,
mutations
})
export default {
addTodo: 'ADD_TODO'
}
export default {
ADD_TODO (state, text) {
state.todos.push(text)
}
}
Vue.use(Vuex)
でセットアップします。
stateだけここで定義してactionsとmutationsは別ファイルにしていますが、ここは好みだと思います。
actionsではここは簡単にADD_TODO
にdispatchしています。外部からajaxで値を持ってくるときなどはここに書くと良さそうです。
mutationsではADD_TODO
を定義しています。これはinput
タグのkeyup
に紐付けられた関数から呼び出されてstate
のtodos
に値を追加することを想定して作られています。
次に親VieModel。
import Vue from 'Vue';
import TextForm from './components/TextForm.vue';
import ToDoList from './components/ToDoList.vue';
import store from './store/';
window.onload = function(){
var main = new Vue({
el: "body",
data: store.state,
components: {
"text-form": TextForm,
"to-do-list": ToDoList
}
})
}
Vueとコンポーネント、それとVuexで作ったstoreを読み込みます。
そして親ViewMoelにstoreとコンポーネントをセットします。
data属性にはstore.state
を入れることで動的にstate
の中身を変えたときに各コンポーネントに反映するようにしています。
次にコンポーネント。
<template>
<div>
<input type="text" v-model="input" @keyup.enter="addTodo"/>
</div>
</template>
<script>
import store from '../store/';
export default {
props: ['input'],
methods: {
addTodo: function(e){
var text = e.target.value;
store.actions.addTodo(text);
e.target.value = '';
}
}
}
</script>
<template>
<ul>
<li v-for="todo in todos">{{todo}}</li>
</ul>
</template>
<script>
export default {
props: ['todos']
}
</script>
コンポーネントはprops
で渡したデータを元に描画を行っています。
actions
で定義したaddToDo
をここで呼び出しています。
気をつけることとして、mutations
で定義したaddToDo
はstate
とtext
の二つの引数を必要としていたのですが、actions
経由で呼び出すときには引数はtext
だけでいいと言うことです。ちょっと調べ切れていないのですが、actions
で呼び出すかていでよろしくやっているもと思われます(詳しくはコードを読んでみよう)。一瞬ちょっと違和感を感じてしまいますね。
addToDo
に渡されたデータを使ってtodos
が更新され、Todoリストが更新されるようになっています。
おわり・感想
まだ使ってみたレベルの話ですが、うまく使えばVue.jsをつかってやっていた開発の辛いところを解消が出来る感触があります。
Vueを使ってFluxをやるときはReduxを使うというやり方もありますが(Vue.jsにreduxを載せた話)。Vue独自のFluxライクな実装が出てきたことにより、Vueに適したやり方も出来るようになってきたのではないでしょうか。
これ以上ライブラリが増えて辛いという面もありますが、追っていくのも楽しそうです。