Vuex

Руководство по использованию Vuex.

Когда использовать?

Vuex используем, когда приложение требует особого контроля и мониторинга данных. В иных случаях будет достаточно самописных db.js файлов или глобальных прототипов Vue.

Разделение бизнес-логики и интерфейса

Vuex запрещено использовать для управления элементами интерфейса (например, добавлять флаги и индикаторы для модальных окон, пагинации, кнопок и т.п.)

Vuex используется только для хранения бизнес-логики приложения: пользователи, настройки, ключи и т.п...

Модульный подход

В зависимости от типа проекта, мы будем использовать или НЕ использовать модульный подход Vuexarrow-up-right.

В малых и средних проектах его использование можно избегать, но в крупных проектах его использование обязательно.

const store = new Vuex.Store({
  modules: {
    account: {
      namespaced: true,

      // содержимое модуля
      state: () => ({ ... }), // состояние модуля автоматически вложено и не зависит от опции пространства имён
      getters: {
        isAdmin () { ... }, // -> getters['account/isAdmin']
      },
      actions: {
        login () { ... }, // -> dispatch('account/login')
      },
      mutations: {
        login () { ... }, // -> commit('account/login')
      },

      // вложенные модули
      modules: {
        // наследует пространство имён из родительского модуля
        myPage: {
          state: () => ({ ... }),
          getters: {
            profile () { ... }, // -> getters['account/profile']
          },
        },

        // большая вложенность с собственным пространством имён
        posts: {
          namespaced: true,

          state: () => ({ ... }),
          getters: {
            popular () { ... }, // -> getters['account/posts/popular']
          },
        }
      }
    }
  }
});

Структура папок при модульном подходе

  • store

    • modules

      • user

        • actions.js

        • getters.js

        • mutations.js

        • index.js

        • state.js

    • actions.js

    • getters.js

    • mutations.js

    • index.js

    • state.js

Причём если у модуля есть свои модули, то вложенность идёт дальше по модулям в соответствии с корнем (как в примере сверху с постами пользователя).

state

Если мы работаем с API и храним полученные от него данные, то они должны оставаться в том же виде, в котором мы их получили с сервера - неизменными. Если какие-либо данные нам нужны в отсортированном виде (либо любом другом), то добавляем в getters новое значение.

Данные из state могут использоваться для чтения в любом месте Vue приложения.

Старайтесь избегать мутаций свойств объектов из state. Нам нужно наиболее предсказуемое поведение приложений.

getters

Геттеры мы используем только для получения данных из state, а также для создания фильтров для данных.

mutations

Вторым параметром мы никогда не передаём название как payload. Мы должны сразу понимать что за сущность мы принимаем в мутацию. Мы также не используем Object-Style Commitarrow-up-right.

Использование Mutation Typesarrow-up-right

Часто встречается шаблон использования констант для типов мутаций в различных реализациях Flux. Это позволяет коду использовать такие инструменты, как линтеры, а размещение всех констант в одном файле позволяет вашим соавторам с первого взгляда получить представление о том, какие мутации возможны во всем приложении:

Это особенно полезно в крупных проектах. В малых и средних проектах это не обязательно.

Мутации должны быть синхронными

Следует помнить одно важное правило: функции обработчика мутаций должны быть синхронными. Почему? Рассмотрим следующий пример:

Теперь представьте, что мы отлаживаем приложение и просматриваем журналы изменений devtool. Для каждой зарегистрированной мутации инструменту разработки необходимо будет делать снимки состояния «до» и «после». Однако асинхронный обратный вызов внутри приведенного выше примера мутации делает это невозможным: обратный вызов еще не вызывается, когда мутация зафиксирована, и инструмент разработки не может узнать, когда на самом деле будет вызван обратный вызов — любая мутация состояния, выполненная в обратном вызове. по существу не отслеживается!

actions

Когда мы используем какой-либо action внутри компонентов, все необходимые мутации должны происходить автоматически. Также мы должны иметь доступ к запрашиваемым данным.

При использовании Promise(), всегда прокидывайте также reject(err)

helper-функции

Функции mapGetters, mapActions, mapMutations, mapState - запрещено использовать.

Вместо этого, используйте варианты:

  • this.$store.state.some_state

  • this.$store.getters['someGetter']

  • this.$store.dispatch('someAction')

  • this.$store.commit('SOME_MUTATION', args)

Last updated