
При написании больших фронтенд-приложений управление состоянием может стать довольно сложной и утомительной задачей.

Для Vue.js был разработан плагин Vuex, предназначенный для управления состоянием. По умолчанию в нем выстроена следующая структура папок:

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

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

Рекомендованная структура Vuex (прим. пер.: на этой картинке автор, вероятно, забыл добавить файл store/modules/user/mutations.js, т.к. он фигурирует далее в коде)
Эта структура папок разбивает хранилище на модули, у каждого из которых есть своя отдельная папка. Папка со всеми модулями находится там же, где и index.js, сгенерированный с помощью Vuex. Как и следовало ожидать, содержимое файла index.js нужно тоже поменять, например на такое:
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/index.js'
Vue.use(Vuex);
export default new Vuex.Store({
    state,
    mutations,
    actions,
    getters,
    modules: {
        user
    }
});
В этом примере я создал модуль «user», импортировал его в index.js, предоставленный библиотекой Vuex. Таким образом, модуль «user» был подключен к хранилищу, и теперь доступен.
Переходя к модулю «user» мы импортируем state, actions, getters и mutations в modules/user/index.js таким образом:
import state from './state.js'
import mutations from './mutations.js'
import actions from './actions.js'
import getters from './getters.js'
export default {
    namespaced: true,
    state,
    mutations,
    getters,
    actions,
}
Если вы заметили, полю namespaced было задано значение true. Это обусловлено тем, что в определенных обстоятельствах мы хотим иметь возможность указать, чтобы определенный модуль искал определенное действие, состояние или геттер. Идем дальше...
Состояние
Из-за перехода от стандартной структуры Vuex к модульной методы, через которые мы получали доступ к состоянию Vuex, нужно изменить. Например, мы не сможем получить доступ к полю userAvatar из состояния модуля «user» простым отображением поля userAvatar на поля объекта вычисляемых свойств (прим. пер.: под простым отображением понимается такой стандартный способ вызова функции mapState: ...mapState(['userAvatar'])}). Так что мы используем функцию mapState (прим. пер.: эта функция автоматически генерирует вычисляемые свойства) в скрипте компонента следующим образом:
import {mapState} from 'vuex'
export default {
    computed: {
        ...mapState({
            userAvatar: state => state.user.userAvatar
        })
    },
}
Выше показан рекомендованный метод получения доступа к состоянию модуля, которое бы выглядело так:
export default {
    userAvatar: "img-location"
};
Действия
Также нельзя ожидать, что действие из модуля «user» будет доступно простым отображением действий на поля объекта методов. Нам бы пришлось указать конкретный модуль, к которому мы пытаемся получить доступ, например:
import {mapActions} from 'vuex'
export default {
    methods: {
        ...mapActions("user", ["getUserInfo"]),
        userInfo() {
            this.getUserInfo()
            // вы могли бы либо отобразить это – как мы сделали выше (прим. пер.: вероятно, имеется в виду строчка <..mapActions("user", ["getUserInfo"]),>), либо вызвать в точности тем же способом, 
            // что использован ниже
            this.$store.dispatch('user/getUserInfo')
            // эти два метода выполняют одну и ту же задачу – вызов действия getUserInfo
        }
    },
}
Выше представлен предпочтительный метод доступа к действию из модульного Vuex в случае использования следующего файла с действиями:
export default {
    getUserInfo() {
        alert('Successful')
    }
}
Мутации
Мутации используются для синхронных функций и чаще всего используются для изменения состояния. Способ получения доступа к мутации также будет другим.
export default {
    methods: {
        setuserInfo() {
            let data = {
                name: 'Henry'
            }
            this.$store.commit('user/setUserInfo', data)
        }
    },
}
Выше представлен рекомендованный способ доступа к мутации в модульном Vuex при использовании такого файла с мутациями:
export default {
    setUserInfo: (state, data) => {
        state.user = data
    }
}
Геттеры
Геттеры подобны вычисляемому свойству компонента. Их используют для вычислений или фильтрации. Типичный случай использования геттеров – сортировка по отличиям в полях или по доступности полей, например:
export default {
    getActiveUsers: state => {
        return state.users.filter(x => x.active === true)
    }
}
Выше – рекомендованный способ объявления или записи геттера, при этом к нему можно получить доступ с помощью отображения геттеров на поля объекта вычисляемых свойств, например вот так:
import {mapState} from 'vuex'
export default {
    computed: {
        ...mapGetters('user', ['getActiveUsers'])
    },
}
Это был долгий путь, надеюсь, что у вас получилось использовать модульный Vuex и писать более чистый код.
 
           
 

Yaschik
Так это же копипаста с официальной документации. Или в России уже запретили и ее?
kentavr009 Автор
А где вы увидели копипасту? Я не нашел… Ну, или я плохо искал
kentavr009 Автор
Списался с автором оригинальной статьи и вот что он ответил по поводу вашего замечания: «Я читал про модульность в документации, и в своей статье попытался разъяснить этот материал другим разработчикам. Подход по сути тот же, что и в документации, но отличие в том, что каждый модуль в своей папке.»