はじめに
Vuexでv-modelを使いたいなぁ、ブラウザバックしたときに入力値が保持されるといいなぁ、と思ったときに実装した内容を残しておきます。
ここでは検索フォームを例に取り上げますが、フォーム入力全般に応用できると思います。
環境
vue @2.6.12
vue-router @3.4.9
vuex @3.6.0
双方向算出プロパティを使う
store.js に関連の処理を書く
まずは、store.js(またはそれに準ずる処理が書かれている場所)に以下のような処理を用意します。ここでは、keyword
というstateを例に取り上げます。
export default new Vuex.Store({
state: { // 1
keyword: ''
},
getters: { // 2
keyword: state => state.keyword
},
mutations: { // 3
setKeyword: function(state, keyword) {
state.keyword = keyword
},
},
actions: { // 4
getKeyword: function({ commit }, keyword) {
commit('setKeyword', keyword)
},
}
})
それぞれの役割
- Vuexのstoreにv-modelで扱いたいstateを用意する。
- gettersでstate.keywordの値を取得できるようにする。
- mutationsでstateの値を書き換えられるようにする。
- actionsでmutationsを呼び出せるようにする。
2)gettersはもとの値を書き換えることがありません。ここでは読み取り専用であることを明示するために、あえてgettersを介しthis.$store.getters.keyword
で値を参照できるようにしています。もちろん this.$store.state.keyword
としてstateから値を参照することもできます。
3)stateの値を変更する処理です。stateの値を変えるときはmutationsを介して変更するようにします。stateを変更する処理が他のコンポーネントに書かれていると管理が煩雑になるためです。
4)さらに3のmutationsをcommitするための処理を書いています。他のコンポーネントからは、このactionsをdispatchすることで処理を行います。もちろんmutationsを直接commitしても問題ありません。
書き方はさまざまありますので、プロジェクト全体のルールに従うのが良いでしょう。
computedをgetとsetに分ける
次に実際に使用したいコンポーネントに移ります。
ここでは、inputタグのv-modelに keyword
を用意しました。
<input type="text" v-model="keyword">
次にcomputedに記述していきます。getとsetに分けて次のように書くことで、読み取りと書き込みの両方を実現できます。
computed: {
keyword: {
get() {
return this.$store.getters.keyword
},
set(value) {
this.$store.dispatch("getKeyword", value);
}
}
}
getはstoreから値を読み取る処理、setは値が変更されたときに実行する処理です。setの引数に、イベントが起こったときの値が入ります。
さきほど、actionsに設定した getKeyword
を呼び出して、引数にvalueを渡すことでstateの値を書き換える処理を行っています。
以上で、Vuexでも、v-modelを扱えるようになります。
さいごに
本稿で取り上げたのは、Vuex公式でフォームの扱いの項目で説明されている内容に基づきます。公式で丁寧に説明がなされているものの該当箇所のみでは全体像がわからないため、関連するコードを記事としてまるっとまとめておきたいと思いました。