Плагины

Хранилища Vuex принимают опцию plugins, предоставляющую хуки для каждой мутации. Vuex-плагин — это просто функция, получающая хранилище в качестве единственного параметра:

const myPlugin = store => {
  // вызывается после инициализации хранилища
  store.subscribe((mutation, state) => {
    // вызывается после каждой мутации
    // мутация передаётся в формате { type, payload }.
  })
}

Используются плагины так:

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

Вызов мутаций из плагинов

Плагинам не разрешается напрямую изменять состояние приложения — как и компоненты, они могут только вызывать изменения опосредованно, используя мутации.

Вызывая мутации, плагин может синхронизировать источник данных с хранилищем данных в приложении. Например, для синхронизации хранилища с вебсокетом (пример намеренно упрощён, в реальной ситуации у createPlugin были бы дополнительные опции):

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 = 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...

    // сохранение состояния для следующей мутации
    prevState = nextState
  })
}

Плагины, снимающие слепки, должны использоваться только на этапе разработки. При использовании Webpack или Browserify, мы можем отдать этот момент на их откуп:

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

Плагин будет использоваться по умолчанию. В production-окружении вам понадобится DefinePlugin для Webpack, или envify для Browserify, чтобы изменить значение process.env.NODE_ENV !== 'production' на false в финальной сборке.

Встроенный плагин логирования

Если вы используете vue-devtools, вам он скорее всего не понадобится

В комплекте с Vuex идёт плагин логирования, который можно использовать при отладке:

import createLogger from 'vuex/dist/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
  }
})

Логирующий плагин можно включить также и используя отдельный тег <script>, помещающий функцию createVuexLogger в глобальное пространство имён.

Обратите внимание, что этот плагин делает слепки состояний, поэтому использовать его стоит только на этапе разработки.

results matching ""

    No results matching ""