plugins.md 4.5 KB

プラグイン

Vuex ストア は、各ミューテーションへのフックを公開する plugins オプションを受け付けます。 Vuex プラグインは、単一の引数としてストアを受けつけるただの関数です:

const myPlugin = store => {
  // ストアが初期化されたときに呼ばれる
  store.subscribe((mutation, state) => {
    // それぞれのミューテーションの後に呼ばれる。
    // ミューテーションは、通常のディスパッチに対して、
    // オブジェクトスタイルディスパッチのための独自のミューテーションオブジェクトのような { type, payload } の形式で提供されます
  })
}

そして、このように利用することができます:

const store = new Vuex.Store({
  // ...
  plugins: [myPlugin]
})

プラグイン内でのディスパッチ

プラグインは、直接、状態を変更することは許されていません。これはコンポーネントに似ています。プラグインは、コンポーネント同様にミューテーションをディスパッチすることによる変更のトリガーによってのみ、状態を変更することができます。

プラグインを、ミューテーションのディスパッチでストアとデータソースの同期をおこなうために利用することができます。 websocket データソースとストアを例にします (これは不自然な例です。実際には、さらに複雑なタスクのために createPlugin 関数は、いくつかのオプションを受け取れます):

export default function createWebSocketPlugin (socket) {
  return store => {
    socket.on('data', data => {
      store.dispatch('RECEIVE_DATA', data)
    })
    store.subscribe((mutation) => {
      if (mutation.type === 'UPDATE_DATA') {
        socket.emit('update', mutation.payload)
      }
    })
  }
}
const plugin = createWebSocketPlugin(socket)

const store = new Vuex.Store({
  state,
  mutations,
  plugins: [plugin]
})

状態のスナップショットを撮る

時々、状態の"スナップショット"を撮って、ミューテーション前後の状態を比較したくなることがあるでしょう。それを実現するために、状態オブジェクトのディープコピーを行う必要があります:

const myPluginWithSnapshot = store => {
  let prevState = _.cloneDeep(store.state)
  store.subscribe((mutation, state) => {
    let nextState = _.cloneDeep(state)

    // 以前の状態と以後の状態を比較...

    // 次のミューテーションのために状態を保存
    prevState = nextState
  })
}

状態のスナップショットを撮るプラグインはアプリケーションの開発の間だけ使われるべきです。 Webpack や Browserify を使っていれば、ビルドツールにそれを処理させることができます:

const store = new Vuex.Store({
  // ...
  plugins: process.env.NODE_ENV !== 'production'
    ? [myPluginWithSnapshot]
    : []
})

上のように記述すれば、プラグインはデフォルトで利用されることになります。本番環境( production ) では、 process.env.NODE_ENV !== 'production'false に置き換えるために、 Webpack ではDefinePlugin 、 Browserify ではenvify が必要になります。

ビルトインロガープラグイン

Vuex には、一般的なデバッグに利用する用途の備え付けのロガープラグインがあります。

import createLogger from 'vuex/logger'

const store = new Vuex.Store({
  plugins: [createLogger()]
})

createLogger 関数はいくつかのオプションを受け取ります:

const logger = createLogger({
  collapsed: false, // ログ出力されたミューテーションを自動で展開します
  transformer (state) {
    // ロギングの前に、状態を変換します
    // 例えば、特定のサブツリーのみを返します
    return state.subTree
  },
  mutationTransformer (mutation) {
    // ミューテーションは、{ type, payload } の形式でログ出力されます
    // 任意の方法でそれをフォーマットできます
    return mutation.type
  }
})

ロガープラグインは、状態のスナップショットを撮ることに注意しましょう。これは、開発を行っている間だけ利用すべきです。