Vuex是一个正式的,文档齐全的应用程序状态管理库,专门为Vue.js设计。 该材料的作者(我们今天将其翻译发表)认为使用此库比Redux更加令人愉悦,因为首先,Vuex需要更少的样板代码,其次,因为它可以工作使用异步机制,这里不需要其他库。 而且,由于Vuex库是由从事Vue的同一团队创建的,因此该库与该框架很好地集成在一起。 不幸的是,在使用Vuex时,您仍然会遇到一个困难,这包括正确准备要使用该库的项目结构。

在本文中,您将找到有关使用Vuex构造大型项目的方法的描述,以及旨在自动创建Vuex模块的过程的脚本。
Vue-企业-样板模式和项目结构问题
Vue的一位开发人员Chris Fritz为Vue创建了一个出色的
模板 ,其中展示的项目结构旨在使用Vuex。 特别是,此模板允许Vuex根据
modules
文件夹中的文件自动注册模块。 项目的文件夹结构可能类似于下图。
项目结构和不便的代码放置使用此模板时,状态,获取器,操作和突变必须在同一文件中。 就我个人而言,我更喜欢将它们保存在单独的文件中,考虑到Vuex模块有时非常大的事实,这使得浏览程序非常方便,而无需滚动大量代码。 遵循这个想法,我们将更改模板中的代码,以便将与各个模块相关的内容分类到用于这些模块的文件夹中。 也就是说,该项目的结构将发生变化,并且与以下所示类似。
项目的结构,包括将模块的材料分解为模块文件夹中的单独文件开发支持便利项目结构的模板
因此,我们将与Vuex一起组织工作,以便我们可以使用类似于项目中上图中所示的文件夹和文件结构。 为此,请首先使用
Vue CLI 3创建一个新项目。
准备好要继续使用的项目模板后,通过在终端中运行
npm install vuex lodash -save
命令来安装Vuex和Lodash。 要使用模块,我们需要Lodash的
camelCase
函数,该函数旨在将字符串转换为骆驼样式。
现在,创建一个文件夹和一个文件结构,类似于上图所示。
让我们从
store.js
文件开始。 这是他的代码:
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
Vue和Vuex被导入到这里,因为我们离不开它们。 另外,我们从
/modules/index.js
导入模块。 接下来,我们初始化存储并遍历所有模块。 如果模块具有
init
操作,我们将初始化模块。 对于那些在应用程序启动时需要初始化的模块来说,这非常有用。 结果,我们当然会导出
store
,然后通常将其导入到
main.js
文件中并添加到Vue实例中。
现在是时候使用
index.js
文件了,该文件位于
/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;
在此代码中,我们首先从Lodash导入
camelCase
函数。 然后,我们使用
require.context
方法连接模块。 作为第三个参数,我们传递一个正则表达式,该表达式将过滤
index.js
文件以及名称包含行,
actions
和获取器行的文件。 它们将被导入到状态文件中,例如
auth.js
,然后导出。 例如,这是
src/store/modules/auth/
文件夹中的
auth.js
文件在工作开始时的样子:
import actions from './actions'; import mutations from './mutations'; import getters from './getters'; const state = { user: null }; export default { state, mutations, getters, actions };
现在只剩下遍历所有模块并与所有模块组成一个单一的对象。 在这里,您需要排除所有具有行
unit
名称的文件,因为它们仅用于测试,而不用于开发或在生产环境中部署项目时需要。 之后,我们向
modules
对象添加一个新属性,该属性将具有状态文件的名称,例如
auth
或
users
。 另外,我们使用
camelCase
函数使属性名称看起来一致。 然后,我们填充
modules
对象,
requireModule
并使用
...requireModule(fileName).default
,然后导出
modules
。
实际上,这就是项目的结构,状态,吸气剂,动作和变异分别存储并方便组织。 现在让我们谈谈如何编写脚本来自动创建Vuex模块。
自动创建Vuex模块的脚本
使用名称
scripts
在项目文件夹中创建一个新文件夹,在其中创建文件
generateVuexModule.js
。 对于此项目,我们将需要Node.js,因此,如果您尚未安装此平台,那么现在是
修复它的时候了。 我们的脚本只有一个依赖项-
chalk
包,用于设计控制台中显示的材料。 您可以使用
npm install -save-dev chalk
安装此软件包。
▍步骤1
在
generateVuexModule.js
文件中,您需要连接三个模块:
fs
,
path
和
chalk
。 同样在这里,您需要一个常量以及指向modules文件夹的路径(
src/store/modules
)和另一个常量
args
,它将在运行脚本时获取传递给脚本的参数。
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; }
如您所见,我们将除前两个
args
外的所有参数都写入
args
,因为它们代表了
node.exe
和脚本文件的路径,并且我们不需要此信息。 我们只对第三个参数感兴趣-新模块的名称。 另外,还有一些功能,
error
和
success
,使用上述
chalk
包显示带有不同颜色文本的消息。
在这里,您需要检查
args
数组的长度,以便确定模块名称是否传递给我们的脚本,如果不是,则给出错误消息。 因此,如果尝试使用
node generateVuexModule.js
命令运行此脚本,而没有向其传递任何其他内容,则您将在终端中看到一条错误消息。
▍步骤2
至此,我们有了模块的名称以及由
modulesPath
常量给出的路径。 但是,我们仍然必须处理这些数据。 即,从
args
数组中提取名称并收集模块的完整路径,更不用说其内容的形成了。
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 { }; `;
模块名称将在索引为0的
args
数组的元素中。在程序的此阶段,我们可以依靠此元素的存在,因为我们之前曾尝试从
process.argv
提取它,然后检查
args
数组的长度。 另外,我们使用
path
模块和
join
方法准备了完整路径。 由于
generateVuexModule.js
文件位于
scripts
项目文件夹中,因此使用
__dirname
构造获取了当前目录,并将其上移了一层。 然后,我们仅将结果添加到常量
modulesPath
的内容和模块的名称中。 此时,
modulePath
常量应包含类似
pathToYourProject/project/src/store/modules/moduleName
。 这是创建模块的地方。 现在,由于我们具有完整路径,因此我们可以检查此目录是否存在。 我们不想意外覆盖现有模块的文件。 结果,如果您计划在其中创建新模块的目录存在,则由于
chalk
,我们将以红色字母显示错误消息。
错误信息示例接下来,您需要创建常量,其中将包含文件的数据。 可以想象,
stateContent
用于状态文件,例如
auth.js
,
exportFileContent
用于
getters.js
,
actions.js
和
mutations.js
文件。 如有必要,您可以将项目中所需的所有内容添加到此列表中。
▍步骤3
现在,我们只需要为模块文件创建路径并创建它们即可。
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!');
首先,我们声明四个常量,每个常量包含对应文件的路径。 接下来,我们需要为模块创建一个文件夹。 我们已经检查了是否存在这样的文件夹,如果存在则给出了错误。 因此,创建文件夹应该没有问题。 最后,我们使用
fs.appendFileSync
,将具有创建过程中指定内容的新文件放置在新创建的目录中。 最后,脚本显示有关成功完成操作的消息。
要使用此脚本,只需在终端中转到项目的
scripts
文件夹,然后运行以下
node generateVuexModule.js yourModuleName
表单
node generateVuexModule.js yourModuleName
。 成功完成脚本后,您将看到有关创建模块的消息。
总结
在阅读了这些材料之后,您了解了用于计划使用Vuex的大型项目的结构模板,以及可简化Vuex模块创建的脚本。 我们希望您发现这些知识有用。 您可以在
此处找到我们检查过的项目代码示例。
亲爱的读者们! 您如何构造使用Vuex的大型Vue应用程序?
