30
24

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がだるくなる問題

Last updated at Posted at 2017-08-29

第9回ペパボテックカンファレンス ~ Vue.js 特集 ~ @Joe_nohさんが「Vuex と入力フォーム」にて、「フォームが多くなると辛い(特にmutation)」と話したが、シンプルにフォームデータをcompのローカルstateに詰め込んで、発火するたびにローカルstate丸ごとstoreに投げればいいじゃないかっと思ってちょっとやってみた。

ゴール

  • mutationsを減らす
  • get, setを減らす
  • Vuex wayを守る
  • vue-devtoolsを手放さない

GitHub:vuex-form-approach
Demo

ポイント1

compのdataを一つのObjectにしておく(profile)

data () {
  return {
    profile: {
      name: '',
      age: 0,
      pet: []
    }
  }
}

ポイント2

全体の発火をしっかりキャッチしてstoreへどん。deep: true が味噌

watch: {
  'profile': {
    handler (val) {
      this.$store.commit('FORM1_UPDATE_PROFILE', cloneDeep(val))
    },
    deep: true
  }
}

ポイント3

profile.pet[0].name が変更されても発火しないので子compを作って深い階層のデータ変更を親に伝えよう。(子compを作らないといけない時点で結局辛いよね?)

onChangePet (val, index) {
  this.profile.pet[index] = val
  this.$store.commit('FORM1_UPDATE_PROFILE', cloneDeep(this.profile))
}

注意

Objectのままstoreに渡す(commit)と「直で変更するな」と怒られるので、immutableなものにしよう。ここではlodashの cloneDeep で解決。

mutationsはこれだけで済む

[FORM1_UPDATE_PROFILE] (state, data) {
  state.profile = data
}

最後に

実務では...そう簡単にはいかないので action に投げて加工してからcommitするんじゃないかな?
これで目的は達成したが、データ丸ごとstoreにってのはお行儀よくないし、入力した値がお互い影響し合うような複雑な業務システムだとバグ出やすいので、面倒だが丁寧に get set を書きたい。

他にいい方法があればぜひ教えてください!

30
24
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
30
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?