Vuex

Plugins

Vuex stores accept the plugins option that exposes hooks for each mutation. A Vuex plugin is simply a function that receives the store as the only argument:

const myPlugin = (store) => {
 // called when the store is initialized
 store.subscribe((mutation, state) => {
 // called after every mutation.
 // The mutation comes in the format of `{ type, payload }`.
 })
}

And can be used like this:

const store = createStore({
 // ...
 plugins: [myPlugin]
})

Committing Mutations Inside Plugins

Plugins are not allowed to directly mutate state - similar to your components, they can only trigger changes by committing mutations.

By committing mutations, a plugin can be used to sync a data source to the store. For example, to sync a websocket data source to the store (this is just a contrived example, in reality the createWebSocketPlugin function can take some additional options for more complex tasks):

export default function createWebSocketPlugin (socket) {
 return (store) => {
 socket.on('data', data => {
 store.commit('receiveData', data)
 })
 store.subscribe(mutation => {
 if (mutation.type === 'UPDATE_DATA') {
 socket.emit('update', mutation.payload)
 }
 })
 }
}
const plugin = createWebSocketPlugin(socket)
const store = createStore({
 state,
 mutations,
 plugins: [plugin]
})

Taking State Snapshots

Sometimes a plugin may want to receive "snapshots" of the state, and also compare the post-mutation state with pre-mutation state. To achieve that, you will need to perform a deep-copy on the state object:

const myPluginWithSnapshot = (store) => {
 let prevState = _.cloneDeep(store.state)
 store.subscribe((mutation, state) => {
 let nextState = _.cloneDeep(state)
 // compare `prevState` and `nextState`...
 // save state for next mutation
 prevState = nextState
 })
}

Plugins that take state snapshots should be used only during development. When using webpack or Browserify, we can let our build tools handle that for us:

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

The plugin will be used by default. For production, you will need DefinePlugin for webpack or envify for Browserify to convert the value of process.env.NODE_ENV !== 'production' to false for the final build.

Built-in Logger Plugin

Vuex comes with a logger plugin for common debugging usage:

import { createLogger } from 'vuex'
const store = createStore({
 plugins: [createLogger()]
})

The createLogger function takes a few options:

const logger = createLogger({
 collapsed: false, // auto-expand logged mutations
 filter (mutation, stateBefore, stateAfter) {
 // returns `true` if a mutation should be logged
 // `mutation` is a `{ type, payload }`
 return mutation.type !== "aBlocklistedMutation"
 },
 actionFilter (action, state) {
 // same as `filter` but for actions
 // `action` is a `{ type, payload }`
 return action.type !== "aBlocklistedAction"
 },
 transformer (state) {
 // transform the state before logging it.
 // for example return only a specific sub-tree
 return state.subTree
 },
 mutationTransformer (mutation) {
 // mutations are logged in the format of `{ type, payload }`
 // we can format it any way we want.
 return mutation.type
 },
 actionTransformer (action) {
 // Same as mutationTransformer but for actions
 return action.type
 },
 logActions: true, // Log Actions
 logMutations: true, // Log mutations
 logger: console, // implementation of the `console` API, default `console`
})

The logger file can also be included directly via a <script> tag, and will expose the createVuexLogger function globally.

Note the logger plugin takes state snapshots, so use it only during development.

AltStyle によって変換されたページ (->オリジナル) /