# Плагины Хранилища Vuex принимают опцию `plugins`, предоставляющую хуки для каждой мутации. Vuex-плагин — это просто функция, получающая хранилище в качестве единственного параметра: ``` js const myPlugin = store => { // вызывается после инициализации хранилища store.subscribe((mutation, state) => { // вызывается после каждой мутации // мутация передаётся в формате `{ type, payload }`. }) } ``` Используются плагины так: ``` js const store = new Vuex.Store({ // ... plugins: [myPlugin] }) ``` ### Вызов мутаций из плагинов Плагинам не разрешается напрямую изменять состояние приложения — как и компоненты, они могут только вызывать изменения опосредованно, используя мутации. Вызывая мутации, плагин может синхронизировать источник данных с хранилищем данных в приложении. Например, для синхронизации хранилища с веб-сокетом (пример намеренно упрощён, в реальной ситуации у `createPlugin` были бы дополнительные опции): ``` js 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) } }) } } ``` ``` js const plugin = createWebSocketPlugin(socket) const store = new Vuex.Store({ state, mutations, plugins: [plugin] }) ``` ### Снятие слепков состояния Иногда плагину может потребоваться "снять слепок" состояния приложения или сравнить состояния "до" и "после" мутации. Для этого используйте глубокое копирование объекта состояния: ``` js const myPluginWithSnapshot = store => { let prevState = _.cloneDeep(store.state) store.subscribe((mutation, state) => { let nextState = _.cloneDeep(state) // сравнение `prevState` и `nextState`... // сохранение состояния для следующей мутации prevState = nextState }) } ``` **Плагины, снимающие слепки, должны использоваться только на этапе разработки.** При использовании webpack или Browserify, мы можем отдать этот момент на их откуп: ``` js const store = new Vuex.Store({ // ... plugins: process.env.NODE_ENV !== 'production' ? [myPluginWithSnapshot] : [] }) ``` Плагин будет использоваться по умолчанию. В production-окружении вам понадобится [DefinePlugin](https://webpack.js.org/plugins/define-plugin/) для webpack, или [envify](https://github.com/hughsk/envify) для Browserify, чтобы изменить значение `process.env.NODE_ENV !== 'production'` на `false` в финальной сборке. ### Встроенный плагин логирования > Если вы используете [vue-devtools](https://github.com/vuejs/vue-devtools), вам он скорее всего не понадобится В комплекте с Vuex идёт плагин логирования, который можно использовать при отладке: ``` js import createLogger from 'vuex/dist/logger' const store = new Vuex.Store({ plugins: [createLogger()] }) ``` Функция `createLogger` принимает следующие опции: ``` js const logger = createLogger({ collapsed: false, // автоматически раскрывать залогированные мутации filter (mutation, stateBefore, stateAfter) { // возвращает `true`, если мутация должна быть залогирована // `mutation` — это объект `{ type, payload }` return mutation.type !== "aBlacklistedMutation" }, transformer (state) { // обработать состояние перед логированием // например, позволяет рассматривать только конкретное поддерево return state.subTree }, mutationTransformer (mutation) { // мутации логируются в формате `{ type, payload }`, // но это можно изменить return mutation.type }, logger: console, // реализация API `console`, по умолчанию `console` }) ``` Логирующий плагин также можно включить напрямую используя отдельный тег `