Vuex:构建大型项目并使用模块

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对象添加一个新属性,该属性将具有状态文件的名称,例如authusers 。 另外,我们使用camelCase函数使属性名称看起来一致。 然后,我们填充modules对象, requireModule并使用...requireModule(fileName).default ,然后导出modules

实际上,这就是项目的结构,状态,吸气剂,动作和变异分别存储并方便组织。 现在让我们谈谈如何编写脚本来自动创建Vuex模块。

自动创建Vuex模块的脚本


使用名称scripts在项目文件夹中创建一个新文件夹,在其中创建文件generateVuexModule.js 。 对于此项目,我们将需要Node.js,因此,如果您尚未安装此平台,那么现在是修复它的时候了。 我们的脚本只有一个依赖项- chalk包,用于设计控制台中显示的材料。 您可以使用npm install -save-dev chalk安装此软件包。

▍步骤1


generateVuexModule.js文件中,您需要连接三个模块: fspathchalk 。 同样在这里,您需要一个常量以及指向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和脚本文件的路径,并且我们不需要此信息。 我们只对第三个参数感兴趣-新模块的名称。 另外,还有一些功能, errorsuccess ,使用上述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.jsexportFileContent用于getters.jsactions.jsmutations.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应用程序?

Source: https://habr.com/ru/post/zh-CN420357/


All Articles