O Vuex é uma biblioteca oficial e bem documentada de gerenciamento de estado de aplicativos, projetada especificamente para o Vue.js. O autor do material, cuja tradução publicamos hoje, acredita que o uso desta biblioteca é muito mais agradável que o Redux, porque, em primeiro lugar, o Vuex requer menos código padrão e, em segundo lugar, pelo fato de funcionar com mecanismos assíncronos, nenhuma biblioteca adicional é necessária aqui. Além disso, como a biblioteca Vuex foi criada pela mesma equipe que trabalha no Vue, essa biblioteca se integra muito bem a essa estrutura. Infelizmente, ao trabalhar com o Vuex, você ainda pode encontrar uma dificuldade, que consiste em preparar adequadamente a estrutura dos projetos nos quais planeja usar esta biblioteca.

Neste artigo, você encontrará uma descrição da metodologia para estruturar grandes projetos usando o Vuex e um script projetado para automatizar o processo de criação dos módulos do Vuex.
Padrão Vue-enterprise-clichê e questão da estrutura do projeto
Um dos desenvolvedores do Vue, Chris Fritz, criou um excelente
modelo para o Vue, a estrutura do projeto apresentada na qual foi projetada para usar o Vuex. Em particular, esse modelo permite que o Vuex registre automaticamente módulos com base nos arquivos da pasta de
modules
. A estrutura de pastas do projeto pode se parecer com a figura a seguir.
Estrutura do projeto e colocação de código inconvenienteAo usar este modelo, é necessário que o estado, getters, ações e mutações estejam no mesmo arquivo. Pessoalmente, prefiro mantê-los em arquivos separados, o que permite, dado que os módulos Vuex às vezes são bastante grandes, é conveniente navegar pelos programas, sem ter que percorrer enormes pedaços de código. Seguindo essa idéia, alteraremos o código do modelo para que o que se relacione com os módulos individuais possa ser classificado em pastas destinadas a esses módulos. Ou seja, a estrutura do projeto mudará e será semelhante à mostrada abaixo.
A estrutura do projeto com a decomposição dos materiais dos módulos em arquivos separados que estão nas pastas dos módulosDesenvolvimento de um modelo que suporta uma estrutura de projeto conveniente
Então, vamos organizar o trabalho com o Vuex para que possamos usar estruturas de pastas e arquivos semelhantes às mostradas na figura anterior em nossos projetos. Para fazer isso, primeiro crie um novo projeto usando o
Vue CLI 3 .
Depois de ter um modelo de projeto pronto para trabalhar com ele, instale o Vuex e o Lodash executando o
npm install vuex lodash -save
no terminal. Para trabalhar com módulos, precisamos da função
camelCase
da Lodash, projetada para converter seqüências de caracteres no estilo camel.
Agora crie uma pasta e uma estrutura de arquivos semelhante à mostrada na figura anterior.
Vamos começar com o arquivo
store.js
. Aqui está o código dele:
import Vue from 'vue' import Vuex from 'vuex' import modules from './modules' Vue.use(Vuex) const store = new Vuex.Store({ modules, strict: process.env.NODE_ENV !== 'production' }) // `init` for (const moduleName of Object.keys(modules)) { if (modules[moduleName].actions.init) { store.dispatch(`${moduleName}/init`) } } export default store
O Vue e o Vuex são importados aqui, pois não podemos ficar sem eles. Além disso, importamos módulos de
/modules/index.js
. Em seguida, inicializamos o armazenamento e percorremos todos os módulos. Se o módulo tiver uma ação
init
, inicializamos o módulo. Isso acaba sendo muito útil para os módulos que precisam ser inicializados quando o aplicativo é iniciado. Como resultado, é claro, exportamos a
store
, após a qual, geralmente, é importada para o arquivo
main.js
e adicionada à instância do Vue.
Agora é hora de trabalhar com o arquivo
index.js
, localizado na pasta
/store/modules
.
// Vuex , . import camelCase from 'lodash/camelCase'; // const requireModule = require.context( // '.', // true, // index.js, , // 'actions', 'mutations', 'getters' . // , .js /^(?!.*(actions|mutations|getters|index)).*\.js$/ ); const modules = {}; requireModule.keys().forEach(fileName => { // if (/\.unit\.js$/.test(fileName)) return; // modules[camelCase(fileName.split('/')[1].replace(/(\.\/|\.js)/g, ''))] = { namespaced: true, ...requireModule(fileName).default }; }); export default modules;
Nesse código, primeiro importamos a função
camelCase
do Lodash. Em seguida, usamos o método
require.context
para conectar os módulos. Como terceiro parâmetro, passamos uma expressão regular para filtrar o arquivo
index.js
, além de arquivos cujos nomes contêm as
actions
,
mutations
e
getters
das linhas. Eles serão importados para o arquivo de status, por exemplo, em
auth.js
e depois exportados. Por exemplo, aqui está como o arquivo
auth.js
da
auth.js
src/store/modules/auth/
pode parecer no início do trabalho:
import actions from './actions'; import mutations from './mutations'; import getters from './getters'; const state = { user: null }; export default { state, mutations, getters, actions };
Agora resta apenas percorrer todos os módulos e formar um único objeto com todos eles. Aqui, você precisa excluir todos os arquivos nos quais existe uma
unit
linha, pois eles são necessários apenas para testes, e não para desenvolvimento ou implantação de um projeto em produção. Depois disso, adicionamos uma nova propriedade ao objeto
modules
, que terá o nome do arquivo de estado, por exemplo,
auth
ou
users
. Além disso, usamos a função
camelCase
para tornar os nomes das propriedades consistentes. Em seguida, preenchemos o objeto
modules
,
requireModule
através do
requireModule
e usando a construção
...requireModule(fileName).default
e exportamos os
modules
.
De fato, é assim que um projeto pode ser estruturado em qual estado, getters, ações e mutações são armazenados separadamente e organizados de maneira conveniente. Agora vamos falar sobre como escrever um script para criar automaticamente módulos Vuex.
Script para criar automaticamente módulos Vuex
Crie uma nova pasta na pasta do projeto com os
scripts
name, nela crie o arquivo
generateVuexModule.js
. Para este projeto, precisaremos do Node.js; portanto, se você não tiver esta plataforma instalada, agora é a hora de
corrigi-la . Nosso script tem apenas uma dependência - o pacote de
chalk
, que é usado para criar materiais exibidos no console. Você pode instalar este pacote com o
npm install -save-dev chalk
.
1Etapa 1
No arquivo
generateVuexModule.js
, é necessário conectar três módulos:
fs
,
path
e
chalk
. Também aqui você precisa de uma constante com o caminho para a pasta modules (
src/store/modules
) e outra constante -
args
, que obterá os argumentos passados para o script quando ele foi executado.
const fs = require('fs'); const path = require('path'); const chalk = require('chalk'); const modulesPath = 'src/store/modules'; const args = process.argv.slice(2); const error = (...args) => { console.log(chalk.red(...args)); }; const success = (...args) => { console.log(chalk.green(...args)); }; if (!args.length) { error('You must provide a name for the module!'); return; }
Como você pode ver, escrevemos todos os argumentos para os
args
exceto os dois primeiros, pois representam o caminho para o
node.exe
e o arquivo de script, e não precisamos dessas informações. Estamos interessados apenas no terceiro parâmetro - o nome do novo módulo. Além disso, existem algumas funções,
error
e
success
, que usam o pacote de
chalk
mencionado acima para exibir mensagens com textos de cores diferentes.
Aqui você precisa verificar o comprimento da matriz
args
para descobrir se o nome do módulo foi passado para o nosso script e, se não for, forneça uma mensagem de erro. Portanto, se você tentar executar esse script usando o comando
node generateVuexModule.js
do
node generateVuexModule.js
, sem passar mais nada, verá uma mensagem de erro no terminal.
2Etapa 2
Neste ponto, temos um nome para o módulo e o caminho fornecido pela constante
modulesPath
. No entanto, ainda temos que trabalhar com esses dados. Ou seja, extraia o nome da matriz
args
e colete o caminho completo para o módulo, sem mencionar a formação de seu conteúdo.
const moduleName = args[0]; const modulePath = path.join(__dirname, '../', modulesPath, moduleName); if (fs.existsSync(modulePath)) { error(`${moduleName} directory already exists!`); return; } const stateContent = `import getters from './getters'; import actions from './actions'; import mutations from './mutations'; const state = {}; export default { state, getters, actions, mutations }; `; const exportFileContent = `import * as types from '@/store/types'; export default { }; `;
O nome do módulo estará no elemento da matriz
args
com o índice 0. Nesse estágio do programa, podemos contar com a presença desse elemento, pois anteriormente tentamos extraí-lo de
process.argv
e verificamos o comprimento da matriz
args
. Além disso, preparamos o caminho completo usando o módulo
path
e o método
join
. Obtivemos o diretório atual usando a construção
__dirname
,
__dirname
um nível acima, pois o arquivo
generateVuexModule.js
está localizado na pasta do projeto de
scripts
. Em seguida, adicionamos ao resultado o conteúdo da constante
modulesPath
e o nome do módulo. Nesse ponto, a constante
modulePath
deve conter algo como
pathToYourProject/project/src/store/modules/moduleName
. É aqui que o módulo será criado. Agora, como temos o caminho completo, podemos verificar se esse diretório existe. Não queremos substituir acidentalmente os arquivos de um módulo existente. Como resultado, se o diretório em que você planeja criar um novo módulo, exibiremos uma mensagem de erro em letras vermelhas, graças ao
chalk
.
Exemplo de mensagem de erroEm seguida, você precisa criar constantes nas quais haverá dados para os arquivos. Como você pode imaginar,
stateContent
usado para o arquivo de estado, por exemplo, para
auth.js
, e
exportFileContent
é usado para
getters.js
,
getters.js
e
mutations.js
. Se necessário, você pode adicionar a esta lista tudo o que é necessário em seu projeto.
3Etapa 3
Agora só precisamos criar caminhos para os arquivos do módulo e criá-los.
const statePath = `${path.join(modulePath, `${moduleName}.js`)}` const gettersPath = `${path.join(modulePath, 'getters.js')}` const actionsPath = `${path.join(modulePath, 'actions.js')}` const mutationsPath = `${path.join(modulePath, 'mutations.js')}` fs.mkdirSync(modulePath); fs.appendFileSync(statePath, stateContent); fs.appendFileSync(gettersPath, exportFileContent); fs.appendFileSync(actionsPath, exportFileContent); fs.appendFileSync(mutationsPath, exportFileContent); success('Module', moduleName, 'generated!');
Primeiro, declaramos quatro constantes, cada uma das quais contém um caminho para o arquivo correspondente. Em seguida, precisamos criar uma pasta para o módulo. Já verificamos se existe uma pasta e, se for o caso, comemos um erro. Portanto, não deve haver problemas com a criação de uma pasta. E, finalmente, usamos os
fs.appendFileSync
, colocando os novos arquivos com o conteúdo especificado no processo de criação deles no diretório recém-criado. No final, o script exibe uma mensagem sobre a conclusão bem-sucedida da operação.
Para usar esse script, basta ir para a pasta
scripts
do seu projeto no terminal e executar um comando do
node generateVuexModule.js yourModuleName
do formulário
node generateVuexModule.js yourModuleName
. Após a conclusão bem-sucedida do script, você verá uma mensagem sobre a criação de um módulo.
Sumário
Depois de revisar este material, você aprendeu sobre um modelo para estruturar grandes projetos em que planeja usar o Vuex e um script que simplifica a criação dos módulos do Vuex. Esperamos que você ache esse conhecimento útil. O código do projeto, exemplos dos quais examinamos, pode ser encontrado
aqui .
Caros leitores! Como você estrutura grandes aplicativos Vue que usam o Vuex?
