Модульность во Vue.js и Vuex

image

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

image

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

image
Структура папок в хранилище Vuex

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

image
О да, я узнал это на собственном горьком опыте

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

image
Рекомендованная структура 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 и писать более чистый код.

ссылка на оригинал статьи https://habr.com/ru/post/509904/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *