目的
VeeValidate + Vuexの実装でいろいろ詰まったので、うまくいった実装例を残す。
背景
VeeValidateはv-modelが前提になっているっぽい。
http://vee-validate.logaretm.com/v2/concepts/components.html
Vuex + value + @inputの組み合わせの事例はいろいろあったが、
Vuex + v-modelの組み合わせは見つからなかったので、うまくいった実装例を残す。
Vuex + VeeValidate でうまくいかなかったこと
v-modelを使わずvalue + @inputの組み合わせだと、手動で入力を伴わずにstateの値を書き換えた場合に、うまくVeeValidateに値の修正が伝わらない。
message.vue
<input name="message" :value="message" @input="message = $event" v-validate="'required|min:5'" type="text">
※VeeValidateを使ってなければ上記実装で特に問題はないが
Vuex + VeeValidate でうまくいった実装例
v-modelと算出プロパティのsetterを使う。
message.vue
<input name="message" v-model="message" v-validate="required|min:5" type="text">
<script>
computed: {
message: {
get () {
return this.$store.state.message;
},
set (val) {
this.$store.commit('UPDATE_MESSAGE', val);
}
}
}
</script>
Vuex + VeeValidate + v-for
算出プロパティのsetterだとv-forのindexを渡せないので、setterで指定した配列箇所のstate更新が実現できない。
そのため、v-modelではstateのコピーを利用してstateは更新せず、別途@inputを定義してstateを更新する。
message.vue
<input v-for"(book index) in books" name="book" v-model="book.title" @input="input(index, $event)" v-validate="required|min:5" type="text">
<script>
computed: {
books() {
return this.$store.state.books.map(v => Object.assign({}, v));
}
}
methods: {
input(index, value) {
this.$store.commit("changeTitle", index, value)
}
}
</script>
store.js
const store = new Vuex.Store({
state: {
books: []
},
mutations: {
changeTitle(state, index, value) {
state.books[index].title = value;
}
}
})