Vuex используем, когда приложение требует особого контроля и мониторинга данных. В иных случаях будет достаточно самописных db.js файлов или глобальных прототипов Vue.
Разделение бизнес-логики и интерфейса
Vuex запрещено использовать для управления элементами интерфейса (например, добавлять флаги и индикаторы для модальных окон, пагинации, кнопок и т.п.)
Vuex используется только для хранения бизнес-логики приложения: пользователи, настройки, ключи и т.п...
Модульный подход
В зависимости от типа проекта, мы будем использовать или НЕ использовать модульный подход Vuex.
В малых и средних проектах его использование можно избегать, но в крупных проектах его использование обязательно.
conststore=newVuex.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 Commit.
Часто встречается шаблон использования констант для типов мутаций в различных реализациях Flux. Это позволяет коду использовать такие инструменты, как линтеры, а размещение всех констант в одном файле позволяет вашим соавторам с первого взгляда получить представление о том, какие мутации возможны во всем приложении:
Это особенно полезно в крупных проектах. В малых и средних проектах это не обязательно.
Мутации должны быть синхронными
Следует помнить одно важное правило: функции обработчика мутаций должны быть синхронными. Почему? Рассмотрим следующий пример:
Теперь представьте, что мы отлаживаем приложение и просматриваем журналы изменений devtool. Для каждой зарегистрированной мутации инструменту разработки необходимо будет делать снимки состояния «до» и «после». Однако асинхронный обратный вызов внутри приведенного выше примера мутации делает это невозможным: обратный вызов еще не вызывается, когда мутация зафиксирована, и инструмент разработки не может узнать, когда на самом деле будет вызван обратный вызов — любая мутация состояния, выполненная в обратном вызове. по существу не отслеживается!
actions
Когда мы используем какой-либо action внутри компонентов, все необходимые мутации должны происходить автоматически. Также мы должны иметь доступ к запрашиваемым данным.
При использовании Promise(), всегда прокидывайте также reject(err)
helper-функции
Функции mapGetters, mapActions, mapMutations, mapState - запрещено использовать.
import Vue from 'vue';
import Vuex from 'vuex';
import state from './state.js';
import actions from './actions.js';
import mutations from './mutations.js';
import getters from './getters.js';
import user from './modules/user';
Vue.use(Vuex);
export default new Vuex.Store({
state,
mutations,
actions,
getters,
modules: {
user,
},
});
const store = new Vuex.Store({
state: () => ({
// обязательно snake_case
user: {...},
csrf: "...",
}),
});
const store = new Vuex.Store({
getters: {
// обязательно camelCase
someGetter (state) {
return state.user;
},
// getter с доп. фильтром извне
someFilteredGetter: (state) => (is_active) => {
return state.users.filter((user) => user.is_active === is_active );
},
},
});
const store = new Vuex.Store({
mutations: {
// обязательно UPPERCASE + snake_case
SET_POSTS: (state, posts) => {
state.posts = posts;
},
},
});