Плагины
Хранилища Vuex принимают опцию plugins
, предоставляющую хуки для каждой мутации. Vuex-плагин — это просто функция, получающая хранилище в качестве единственного параметра:
const myPlugin = store => {
// вызывается после инициализации хранилища
store.subscribe((mutation, state) => {
// вызывается после каждой мутации
// мутация передаётся в формате `{ type, payload }`.
})
}
Используются плагины так:
const store = createStore({
// ...
plugins: [myPlugin]
})
Вызов мутаций из плагинов
Плагинам не разрешается напрямую изменять состояние приложения — как и компоненты, они могут только вызывать изменения опосредованно, используя мутации.
Вызывая мутации, плагин может синхронизировать источник данных с хранилищем данных в приложении. Например, для синхронизации хранилища с веб-сокетом (пример намеренно упрощён, в реальной ситуации у createWebSocketPlugin
были бы дополнительные опции):
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]
})
Снятие слепков состояния
Иногда плагину может потребоваться «снять слепок» состояния приложения или сравнить состояния «до» и «после» мутации. Для этого используйте глубокое копирование объекта состояния:
const myPluginWithSnapshot = store => {
let prevState = _.cloneDeep(store.state)
store.subscribe((mutation, state) => {
let nextState = _.cloneDeep(state)
// сравнение `prevState` и `nextState`...
// сохранение состояния для следующей мутации
prevState = nextState
})
}
Плагины, снимающие слепки, должны использоваться только на этапе разработки. При использовании webpack или Browserify, можно отдать этот момент на их откуп:
const store = createStore({
// ...
plugins: process.env.NODE_ENV !== 'production'
? [myPluginWithSnapshot]
: []
})
Плагин будет использоваться по умолчанию. В production-окружении понадобится DefinePlugin для webpack, или envify для Browserify. Чтобы изменить выражение process.
на значение false
в финальной сборке.
Встроенный плагин логирования
В комплекте с Vuex идёт плагин логирования, который можно использовать при отладке:
import { createLogger } from 'vuex'
const store = createStore({
plugins: [createLogger()]
})
Функция createLogger
принимает следующие опции:
const logger = createLogger({
collapsed: false, // автоматически раскрывать залогированные мутации
filter(mutation, stateBefore, stateAfter) {
// возвращает `true`, если мутация должна быть залогирована
// `mutation` — это объект `{ type, payload }`
return mutation.type !== 'aBlocklistedMutation'
},
actionFilter (action, state) {
// аналогично `filter`, но для действий
// `action` будет объектом `{ type, payload }`
return action.type !== 'aBlocklistedAction'
},
transformer(state) {
// обработать состояние перед логированием
// например, позволяет рассматривать только конкретное поддерево
return state.subTree
},
mutationTransformer(mutation) {
// мутации логируются в формате `{ type, payload }`,
// но это можно изменить
return mutation.type
},
actionTransformer (action) {
// аналогично `mutationTransformer`, но для действий
return action.type
},
logActions: true, // логирование действий
logMutations: true, // логирование мутаций
logger: console // реализация API `console`, по умолчанию `console`
})
Логирующий плагин также можно включить напрямую используя отдельный тег <script>
, помещающий функцию createVuexLogger
в глобальное пространство имён.
Обратите внимание, что этот плагин делает слепки состояний, поэтому использовать его стоит только на этапе разработки.