37
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

vuexのstateとform binding

Last updated at Posted at 2018-11-24

vuex stateとform bindingのパターンと、
どの方式で試すかの試行錯誤メモ
(vuex側のcodeは省略してます)

computed propertyで吸収

<input type="text" v-model="parameterName" />
<input type="text" v-model="parameterTel" />
computed: {
  ...mapState(['parameters']),
  parameterName: {
    get() { return this.parameters.name },
    set(v) { this.$store.commit('updateParameters', { name: v }) },
  },
  parameterTel: {
    get() { return this.parameters.tel },
    set(v) { this.$store.commit('updateParameters', { tel: v }) },
  },
}
  • v-modelが使える
  • 値は即時stateに反映される
  • bindしたい値ごとにcomputed propertyの定義が必要
    • このままだと名前付けも冗長になるため、parameters form部を別componentに切り出すのが良い

面倒...computed propertyだらけになる

eventで反映

<input type="text"
  :value="parameters.name"
  @change="updateParameters('name', $event)" />
<input type="text"
  :value="parameters.tel"
  @change="updateParameters('tel', $event)" />
computed: {
  ...mapState(['parameters'])
},
method: {
  updateParameters (key, value) {
    this.$store.commit('updateParameters', { [key]: value })
  }
}
  • v-modelの代わりに、:value, @change
  • 値は即時stateに反映される

一番正攻法な気がする

viewで異なるobjectとして扱い、deep watchで反映

<input type="text" v-model="parameters.name" />
<input type="text" v-model="parameters.tel" />
beforeMount: {
  this.parameters = _.cloneDeep(this.$store.state.parameters)
},
data: {
  parameters: {}
},
watch: {
  parameters: {
    handler: function (v, old) {
      this.$store.commit('updateParameters', v)
    },
    deep: true
  }
}
  • v-modelが使える
  • 値は即時stateに反映される
  • templateの見通しが良い
  • 比較的、処理が重い
    • event連携(v-model含む)と違って、object内の全ての値がobserveしてるため
    • bindするobjectのpropertyが大量 or 階層が深い場合、cloneDeepの処理で必要なpropertyだけ切り出すなど考えた方が良い

codeはsimple. 処理は重め

viewで異なるobjectとして扱い、eventで反映

<input type="text"
  :v-model="parameters.name" @change="updateParameters" />
<input type="text"
  :v-model="parameters.tel" @change="updateParameters" />

or

<input type="text" :v-model="parameters.name" />
<input type="text" :v-model="parameters.tel" />
<button @click="updateParameters">検索</button>
beforeMount: {
  this.parameters = _.cloneDeep(this.$store.state.parameters)
},
data: {
  parameters: {}
},
method: {
  updateParameters () {
    this.$store.commit('updateParameters', this.parameters)
  }
}
  • v-modelが使える
  • 値はstateに即時反映と任意のタイミングの反映のどちらも可能
  • 編集状況のdataはview側で管理し、サーバーの最新データはvuex stateで分けて管理できる

結論

様々なケースに柔軟に対応できるので最後のコレが良さそう

viewで異なるobjectとして扱い、eventで反映

下記のような様々なケースに対応しやすそう

  • viewの編集作業をキャンセル
    • vuex stateからデータ取り直しだけで済み低負荷
  • 編集途中に他画面に遷移した場合、その編集内容は他画面に共有されないようにしたい
    • 気づかず誤って編集してしまっていた場合も含む
  • 検索条件formでは、次の検索まで今表示されてるデータの検索条件はvuexに残したい
    • 結果に条件を表示したいケース
    • 定期pollingでデータ再取得をしたいケース
  • websocketでリアルタイム更新時、vuex stateは最新化したいが、formにまで反映させたくないケース

etc..

37
36
0

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
37
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?