|
| 1 | +# プラグイン |
| 2 | + |
| 3 | +Vuex ストア は、各ミューテーションへのフックを公開する `plugins` オプションを受け付けます。 Vuex プラグインは、単一の引数としてストアを受けつけるただの関数です: |
| 4 | + |
| 5 | +``` js |
| 6 | +const myPlugin = store => { |
| 7 | + // ストアが初期化されたときに呼ばれる |
| 8 | + store.on('mutation', (mutation, state) => { |
| 9 | + // それぞれのミューテーションの後に呼ばれる。 |
| 10 | + // ミューテーションは、通常のディスパッチに対して、 |
| 11 | + // オブジェクトスタイルディスパッチのための独自のミューテーションオブジェクトのような { type, payload } の形式で提供されます |
| 12 | + }) |
| 13 | +} |
| 14 | +``` |
| 15 | + |
| 16 | +そして、このように利用することができます: |
| 17 | + |
| 18 | +``` js |
| 19 | +const store = new Vuex.Store({ |
| 20 | + // ... |
| 21 | + plugins: [myPlugin] |
| 22 | +}) |
| 23 | +``` |
| 24 | + |
| 25 | +### プラグイン内でのディスパッチ |
| 26 | + |
| 27 | +プラグインは、直接、状態を変更することは許されていません。これはコンポーネントに似ています。プラグインは、コンポーネント同様にミューテーションをディスパッチすることによる変更のトリガーによってのみ、状態を変更することができます。 |
| 28 | + |
| 29 | +ミューテーションのディスパッチによって、プラグインをストアとデータソースの同期をおこなうために利用することができます。 websocket データソースとストアを例にします (これは不自然な例です。実際には、さらに複雑なタスクのために `createPlugn` 関数は、いくつかのオプションを受け取れます): |
| 30 | + |
| 31 | +``` js |
| 32 | +export default function createWebSocketPlugin (socket) { |
| 33 | + return store => { |
| 34 | + socket.on('data', data => { |
| 35 | + store.dispatch('RECEIVE_DATA', data) |
| 36 | + }) |
| 37 | + store.on('mutation', (mutation) => { |
| 38 | + if (mutation.type === 'UPDATE_DATA') { |
| 39 | + socket.emit('update', mutation.payload) |
| 40 | + } |
| 41 | + }) |
| 42 | + } |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +``` js |
| 47 | +const plugin = createWebSocketPlugin(socket) |
| 48 | + |
| 49 | +const store = new Vuex.Store({ |
| 50 | + state, |
| 51 | + mutations, |
| 52 | + plugins: [plugin] |
| 53 | +}) |
| 54 | +``` |
| 55 | + |
| 56 | +### 状態のスナップショットを撮る |
| 57 | + |
| 58 | +時々、状態の"スナップショット"を受け取りたくなるはずです、そして、ミューテーション前後の状態を比較したくなるでしょう。それを実現するために、状態オブジェクトのディープコピーを行うことが必要になるはずです: |
| 59 | + |
| 60 | +``` js |
| 61 | +const myPluginWithSnapshot = store => { |
| 62 | + let prevState = _.cloneDeep(store.state) |
| 63 | + store.on('mutation', (mutation, state) => { |
| 64 | + let nextState = _.cloneDeep(state) |
| 65 | + |
| 66 | + // 以前の状態と以後の状態を比較... |
| 67 | + |
| 68 | + // 次のミューテーションのために状態を保存 |
| 69 | + prevState = nextState |
| 70 | + }) |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +**状態のスナップショットを撮るプラグインは開発の間だけ使われるべきです。** Webpack や Browserify を使っていれば、ビルドツールにそれを処理させることができます: |
| 75 | + |
| 76 | +``` js |
| 77 | +const store = new Vuex.Store({ |
| 78 | + // ... |
| 79 | + plugins: process.env.NODE_ENV !== 'production' |
| 80 | + ? [myPluginWithSnapshot] |
| 81 | + : [] |
| 82 | +}) |
| 83 | +``` |
| 84 | + |
| 85 | +プラグインはデフォルトで利用されることになります。本番環境( production ) では、最終的に `process.env.NODE_ENV !== 'production'` を `false` に置き換えるために、 Webpack では[DefinePlugin](https://webpack.github.io/docs/list-of-plugins.html#defineplugin) 、 Browserify では[envify](https://github.com/hughsk/envify) が必要になります。 |
| 86 | + |
| 87 | +### ビルトインロガープラグイン |
| 88 | + |
| 89 | +Vuex には、一般的なデバッグに利用する用途の備え付けのロガープラグインがあります。 |
| 90 | + |
| 91 | +```js |
| 92 | +import createLogger from 'vuex/logger' |
| 93 | + |
| 94 | +const store = new Vuex.Store({ |
| 95 | + plugins: [createLogger()] |
| 96 | +}) |
| 97 | +``` |
| 98 | + |
| 99 | +`createLogger` 関数はいくつかのオプションを受け取ります: |
| 100 | + |
| 101 | +``` js |
| 102 | +const logger = createLogger({ |
| 103 | + collapsed: false, // ログ出力されたミューテーションを自動で展開します |
| 104 | + transformer (state) { |
| 105 | + // ロギングの前に、状態を変換します |
| 106 | + // 例えば、特定のサブツリーのみを返します |
| 107 | + return state.subTree |
| 108 | + }, |
| 109 | + mutationTransformer (mutation) { |
| 110 | + // ミューテーションは、{ type, payload } の形式でログ出力されます |
| 111 | + // 任意の方法でそれをフォーマットできます |
| 112 | + return mutation.type |
| 113 | + } |
| 114 | +}) |
| 115 | +``` |
| 116 | + |
| 117 | +ロガープラグインは、状態のスナップショットを撮ることに注意しましょう。これは、開発を行っている間だけ利用すべきです。 |
0 commit comments