层次和约束:项目中使用vuex的3条优化方案

问题描述

使用vuex的store的过程中,发现了一些不是很优雅的地方:

  1. store层module太多,找state、getter、mutation、action对应的module比较慢。

  1. 组件里面mapGetters、mapActions、mapMutations过多,分不清getter、action、mutation属于哪个module,比较混乱。

  1. 没有使用mutation type 和action type的枚举常量来约束action type和mutation type取值,字符串方式容易出错。(如上图)

解决方案

针对这3个问题,制定了3条重构方案。

1. module聚类分层

按照聚类分层思想,当业务复杂后,需要通过一定的聚类特征对扁平化的结构进行分层。

这里按照数据的用途分了page、components、domain、other这四类,page存储页面组件的数据,components存储基础组件的数据,domain存储实体的数据,other存储其他全局数据。

之前的modules

之后的modules

目前还没有存储实体数据的module,所以暂时为空

2.module添加namespace

store划分module是因为不同的数据有不同的归属。

如果想要每个module都能响应全局action的话,不需要加namespace,但是我们并没有没有一个action对应多个module的action handler的情况。反而因为没有加namespace,导致组件里的多个module的getter、action、mutation都扁平的堆在一起,结构混乱、不清晰。

    ...mapMutations([changeisIceTree: 'changeisIceTree',changeIceTreeStatus: 'changeIceTreeStatus',showToast: 'showToast',changeremainingfronzeTime: 'changeremainingfronzeTime',decreaseremainingfronzeTime: 'decreaseremainingfronzeTime',changeiceTreeFadeout: 'changeiceTreeFadeout',changeiceTreeFadeIn: 'changeiceTreeFadeIn',changefrozenTimes: 'changefrozenTimes',changetreecurTime: 'changetreecurTime',changequickTreeMedal:'changequickTreeMedal',changequickHonorMedal:"changequickHonorMedal",upDatePopUpOptionStatus: 'upDatePopUpOptionStatus'}),

一堆的mutation让人迷惑,结构很不清晰,哪个mutation是哪个module必须去store中找。

加上namespace之后,每个mutaion属于一个namespace,每个namespace代表一个module,在组件里就可以轻松的根据namespace区分出哪个module来。

...mapGetters('aaaaa',['mutation111111','mutation22222','mutation33333'
]);
...mapMutations('aaaaa',['mutation111111','mutation22222','mutation33333'
]);
...mapMutations('bbbbb',['mutation4444444','mutation555555','mutation666666',
]);

这样重构之后,组件用到再多module的action、getter、mutation也不会混乱了。

3.mutation type和action type使用枚举常量约束

mutation type和action type的名字可能会写错,因为没有使用typescript,没有类型约束,如果写错了,编译时无法检查出来,只能在运行时检查。解决这个问题或者使用ts,或者全部的mutation type和action type从枚举常量中取。

store中的数据是模块化的,mutation type 和action type的枚举常量自然也是,但是vuex的module并不会处理这两者,想把这些模块化的motation type和action type挂到store实例上,可以通过vuex插件来解决。

我发现社区并没有我需要的vuex插件,于是我自己封装了一个

/*** 生成文件对应的模块* * @param {*} dirPath 文件夹路径*/
const generateModules = (files) => {const modules = {}files.keys().forEach(key => {modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default})return modules;
}/*** 所有file* */
const allFiles = {page: require.context('../modules/page', false, /\.js$/),components: require.context('../modules/components', false, /\.js$/),domain: require.context('../modules/domain', false, /\.js$/),other: require.context('../modules/other', false, /\.js$/)
}/*** 所有module* */
const allModules = {page: generateModules(allFiles.page),components: generateModules(allFiles.components),domain: generateModules(allFiles.domain),other: generateModules(allFiles.other)
}/*** 根据types获取modules下的多个模块的结构化数据* @param {*} types module type* @param {*} fieldName 字段名*/
const getStructuredData = (types, fieldNames) => {const structuredData = {};types.forEach(type => {const modules = allModules[type];const structuredModuleData = Object.keys(modules).map(moduleName => {const fields = fieldNames.map(fieldName => modules[moduleName][fieldName])return {[moduleName]: Object.assign(...fields)}});structuredData[type]= structuredModuleData && structuredModuleData.length ? Object.assign(...structuredModuleData): {};})return structuredData
}const enumTypePlugin = store => {const mutationTypeEnum = getStructuredData(['page','components','domain','other'], ['mutationTypes']);const actionTypeEnum = getStructuredData(['page','components','domain','other'], ['actionTypes']);store.mutationTypes = mutationTypeEnum;store.actionTypes = actionTypeEnum;
}
module.exports = enumTypePlugin;

添加到vuex的plugins中

import typeEnumPlugin from './type-enum-plugin';new Vuex.Store(modules,plugins: [typeEnumPlugin]
)

module定义时导出mutation types和action types

module.exports = {state,getters,mutations,actions,mutationTypes,actionTypes
}

在组件里面就可以使用action type和mutation type来mapAction,mapMutation

...mapActions({mutation1: this.$store.mutationTypes.page.aaa.mutation1,mutation2: this.$store.mutationTypes.page.aaa.mutation2,mutation3: this.$store.mutationTypes.page.aaa.mutation3
})
...mapActions({action1: this.$store.actionTypes.page.aaa.action1,action2: this.$store.actionTypes.page.aaa.action2,action3: this.$store.actionTypes.page.aaa.action3
})

或者像下面这样全部导入

...mapMutations(this.$store.mutationTypes.page.aaa)
...mapActions(this.$store.actionTypes.page.aaa)

这样就避免了手写字符串可能出错的问题。

总结

针对vuex store的module过多,组件里无法区分出getter、action、mutation属于哪一个module,mutation type和action type无约束这3个问题,针对性的提出了3条解决方案:

module聚类分层,分成page、components、domain、other四个文件夹存放module;

添加namespace,组件中使用mapGetters、mapActions、mapMuatations时加上namespace区分;

module定义时导出mutation types和action types,并通过vuex的插件挂到store上,组件中使用mapMutations和mapActions不再通过字符串取对应值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367412.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux脚本编写规则,shell脚本编写守则

现在centos7中使用的是bash软件,通过以下命令可以查看bash版本:[rootlocalhost ~]# cat /etc/redhat-release #查看系统的版本CentOS Linux release 7.5.1804 (Core) #我这里使用的是centos 7.5 1804[rootlocalhost ~]# bash --version #查看bash的版本G…

luogu P2516 [HAOI2010]最长公共子序列

传送门 首先那个\(O(n^2)\)的dp都会吧,不会自己找博客或者问别人,或是去做模板题(误) 对以下内容不理解的,强势推荐flash的博客 我们除了原来记录最长上升子序列的\(f_{i,j}\),再记\(g_{i,j}\)表示到\(i,j\)时的最长上升子序列个数,同时设两个字符串为\(A,B\) 若\(A_iB_j\) ,则…

怎么让员工服从管理_为什么现在的员工执行力和服从性越来越差,管理一严格就辞职?...

当有负面情绪的时候,不要说。管好自己的嘴,有时候做哑巴,是一种境界。现在的企业很多都存在这个问题,员工执行力越来越差,服从性也越来越差,管理者稍微一严格,员工就会辞职走人,留不…

Spring Data REST的实际应用

什么是春天数据休息? spring-data-rest是spring-data项目的新增功能,它是一个框架,可帮助您将实体直接作为RESTful Web服务端点公开。 与rails,grails或roo不同,它不会生成任何实现此目标的代码。 spring data-rest支持…

2018上半年掘金微信群日报优质文章合集:前端篇

在掘金微信交流群里的小伙伴们,你们每天都还在坚持读小报吗?如果你的回答是yes,那真的要给你点一万个赞了?能坚持这么久,真的很优秀噢!(嗯,每天坚持给大家收集文章的小饼也很优秀?&#xff09…

linux运维笔试题目,linux运维相关的笔试题目_笔试题目

一、Linux系统和shell1、写一个sed命令,修改/tmp/input.txt文件的内容,要求:①删除所有空行;②在非空行前面加一个“AAA”,在行尾加一个“BBB”,即将内容为“11111”的一行改为:“AAA11111BBB”…

python之路--day17-shelve,xml和re模块

shelve模块 shelve模块只有一个open函数,返回类似字典的对象,可读可写,key必须为字符串,而值可以是python所支持的数据类型 1 import shelve2 # info1{age:18,height:180,weight:80}3 # info2{age:73,height:150,weight:80}4 #5 #…

20172314 2018-2019-1《程序设计与数据结构》第一周学习总结

教材学习内容总结 概述 软件工程:是一门关于高质量软件开发的技术和理论的学科,用来控制开发过程,实现高质量的软件。软件工程的目标:正确性、可靠性、健壮性、可用性、可维护性、可重用性、可移植性、运行效率。 对于可靠性和健壮…

activiti api文档_【白银人机】Activiti 工作流从入门到入土:完整 hello world 大比拼(API 结合实例讲解)...

点击上方“好好学java”,选择“置顶”公众号重磅资源、干货,第一时间送达重磅推荐 ① 纯福利 | 公众号资源大汇总,一年才一次!② 重磅!!2018年Java全套入门到进阶学习视频及项目实战③ 2018年java架构师学习…

弹簧可配置魔术

Spring框架有几个提供一系列服务的模块,其中许多模块仅可用于托管对象(Spring Bean)。有关这些服务的一些示例是依赖注入,事务管理,AOP服务等。当我们使用时,一切都很好对象即服务,因此由Spring…

前端解读控制反转(IOC)

前言 随着前端承担的职责越来越重,前端应用向着复杂化、规模化的方向发展。大型项目模块化是一种趋势,不可避免模块之间要相互依赖,此外还有很多第三方包。这样的话如何去管理这些繁杂的文件,是一个不可避免的话题。此时作为一种…

ASP.NET MVC传递参数(model), 如何保持TempData的持久性

一看到此标题,相信你也会。因为路由是可以从URL地址栏传过去的。但是Insus.NET不想在地址栏传递,还是一个条件是jQuery的Ajax进行POST的。Insus.NET不清楚别人是怎样处理的,但是这个让Insus.NET花上不少时间来解决。Insus.NET实现的方法也很简…

深度学习语音降噪方法对比_人工智能-关于深度学习的基础方法

深度学习概述深度学习的一些简介,其要点如下:深度学习实际上是基于具有多个隐藏层的神经网络的学习;深度学习的思想来源于人类处理视觉信息的方式;深度学习的发展得益于数据的井喷和计算力的飙升;深度学习的理论基础依…

通过adb巧用monkey获取android设备中所有应用的主activity

由于工作需要,想获取所有应用的activity(这里仅限应用的主入口Launcher activity),搜索了一下,网上实现的方案都是基于android编程实现的,对于不懂开发的测试来说稍有难度,而且对于PC端测试工具来说可行性略差。 给大家…

linux转换vcf格式,如何使用awk分割vCard通讯录文件(.vcf)

写这个的缘由是某人最近要从某旧山寨手机给某(更旧的)NOKIA手机同步通讯录,由于某山寨android手机输出的vCard文件是单文件里面包含多个记录数据的格式,而NOKIA的古老同步软件只支持单记录vcf,所以就要将单个vCard文件分割成多个vcf&#xff…

PWA · 前后端协作 · Node | JTalk 掘金线下活动第七期

通知 余票仅剩 3张,欢迎加入活动群获取更多通知。北京的小伙伴可以关注我们的 JTalk 第八期:前端安全 | 美团点评技术团队专场 ? 报名 扫码报名: 报名链接:点我报名 ? 介绍 本期 JTalk 来杭州啦! 掘金线下活动 J…

替代JavaOne 2013

我对无法参加JavaOne 2013感到很失望,但是很高兴看到涵盖这个年度会议的大量有用帖子。 在这篇文章中,我链接到许多这些资源,并提供了每篇文章相对于JavaOne 2013讨论内容的简短摘要。 主题演讲 主题演讲是“大公告”趋向于发生的地方。 幸运…

指数函数中x的取值范围_基本初等函数I: 指数函数、对数函数和幂函数

本文大约4800字, 建议学习时间1个小时.在学习过一次函数和二次函数(修改版)后, 我们知道, 一次函数ykxb当一次项系数k大于零时是增函数, 小于零时是减函数. 二次函数yax2bxc当二次项系数a大于零时图象沿x轴从左向右先减后增, a小于零时先增后减. 可以想象, 次数更高的函数, 在定…

Linux系统之TroubleShooting(启动故障排除)

尽管Linux系统非常强大,稳定,但是我们在使用过程当中,如果人为操作不当,仍然会影响系统,甚至可能使得系统无法开机,无法运行服务等等各种问题。那么这篇博文就总结一下一些常见的故障排除方法,但…

皮肤可配置化:变量、样式分离

之前皮肤开发了一个版本,抽是抽出来了,但是变量只抽出了几个颜色,没什么价值(上个版本开发过程), 这次我又进行了一次迭代,现在是一个较成熟的版本了。整体理一下思路,可以总结为3步…