じまろぐ

めめ

vuex-connectでnamespacedなmoduleを使いやすくするヘルパーを作った

vuex-connectはVuexでReduxのconnectのようにstoreとコンポーネントを繋ぐやつ。

www.npmjs.com

コンポーネントとstoreを繋ぐ部分を切り離せて宣言的に書けて気に入ってる。mapStateとかVuexが用意してるやつ使わなくてもstoreの値を取り出せて注入できる。

namespacedなmoduleを繋ぐとき

たとえば次のようなstoreがあったとき

const store = new Vuex.Store({
  state: {
    foo: 'foo',
  },
  modules: {
    moduleName: {
      namespaced: true,
      state: {
        bar: 'bar',
      },
      mutations: {
        barMutation(state, payload) {
          state.bar = payload
        },
      },
      actions: {
        barAction({ commit }, payload) {
          commit('barMutation', payload)
        },
      },
      getters: {
        barbar: state => state.bar + state.bar,
      },
    },
  },
})

vuex-connectではこう、関数で書いて階層たどってreturn。

import { connect } from 'vuex-connect'
import MyComponent from './MyComponent'

export default connect({
  stateToProps: {
    foo: 'foo',
    bar: state => state.moduleName.bar,
  },
})(MyComponent)

mapXxxxxぽく書きたいからヘルパー作った

数が少なければいいんだけど多くなってくると毎回namespaceの階層まで記述するのめんどい、のでヘルパー関数作った。

www.npmjs.com

import { connect } from 'vuex-connect'
import { stateToProps } from 'vuex-connect-namespace-helper'
import MyComponent from './MyComponent'

export default connect({
  stateToProps: {
    foo: 'foo',
    ...stateToProps('moduleName', {
      bar: 'bar',
    }),
  },
})(MyComponent)

mapXxxxxとかと同じように1つ目の引数にnamespaceを指定、そのあとそのmoduleのlocal stateを指定する。

ヘルパーがやってるのは指定されたnamespaceとstate名をいい感じにマッピングして、moduleのstateを返す関数に変換してるだけ。

API

内部的にやってることはほぼ同じだけど一応わけてある。

helperFunction(namespace, options) -> Object

  • stateToProps
  • gettersToProps
  • mutationsToEvents
  • mutationsToProps
  • actionsToEvents
  • actionsToProps

vuex-connectおすすめ

VuexのmapXxxxxを無計画に使ってるとつらみになりがちで

  • storeと密結合になるからmapXxxxxをpresentationなコンポーネントには使いたくない
  • コンポーネントごとに小さなcontainerを都度作るのつらい
  • pageレベルのcontainerにやらせるとmapXxxxxが増えまくってつらい
  • コンポーネント$emitをバケツリレーしてcontainerでmapMutationsとかした処理呼ぶのつらい

とかとか。

この辺りをスッと綺麗に書けるようになるので、Vuex使う人は一度試してみるのおすすめです。

starください。

github.com

github.com