背景:在需求开发的过程中,一些接口返回的结果中有很多字段需要在页面上显示出来。通常,可以将这些字段封装为.vue文件中的计算属性,或者将相应的字段重新赋值给data中的字段,方便使用。如下:computed(){count1(){returnthis.targetObj.count1},count2(){returnthis.targetObj.count2},//...//想象一下。相似的代码你要写5遍、10遍}但是无论哪种方式,都会带来大量的代码冗余,让人极度难受。为了解决这个现象,本文借鉴了vuex中使用map方法的思路,大大减少了冗余代码,并且可以对数据的获取进行统一的容错处理。map方法:vuex中基本的状态提取方法可以使用如下方式:computed(){count(){returnthis.$store.count}}同时vuex也注意到了这个问题,当有一个大量的数据需要在store中获取,同时这种方式会产生很大的代码冗余,代码会处处重复。您会看到很多计算属性定义,以及长长的对象属性提取链。所以vuex定义了一个map方法来批量获取store中的指定数据。这个map方法实际上是一个工厂函数(高阶函数),用来产生特定形式的函数。以下是源代码。可以看到mapState最终会返回一个对象res,res中的每一个属性都是一个方法,这个方法返回state中的值。varmapState=normalizeNamespace(function(namespace,states){//定义一个对象来存储获取指定属性的方法varres={};normalizeMap(states).forEach(function(ref){varkey=ref.key;varval=ref.val;//定义获取指定对象中指定属性的方法res[key]=functionmappedState(){varstate=this.$store.state;vargetters=this.$store.getters;//根据namespace查找指定store模块对象if(namespace){varmodule=getModuleByNamespace(this.$store,'mapState',namespace);if(!module){return}state=module.context.state;getters=module.context.getters;}//获取指定命名空间获取的store模块中的属性returntypeofval==='function'?val.call(this,state,getters):state[val]};});//返回函数对象returnres});应用:按照这个思路,可以优化获取复杂对象中字段的方法。定义的工厂函数如下exportconstmapTargetValue=(nameSpace,keyList=[])=>{constresult={}//注意:返回的方法不要使用箭头函数,否则得不到这个//这样既兼容了keyList的每种形式,参考mapState中属性重命名的使用形式if(Array.isArray(keyList)){keyList.forEach(key=>result[key]=function(){//这里假设可以直接在this上获取获取命名空间对象//当然获取指定对象的复杂度取决于你的代码逻辑returnthis[nameSpace][key]||0})}elseif(typeofkeyList==='object'&&keyList){for(letkeyinkeyList){result[keyList[key]]=function(){returnthis[nameSpace][key]||0}}}returnresult}定义的方法与mapState完全相同。与之前的取值方式相比,可以大大减少重复代码量。具体应用计算如下:{...mapTargetValue("targetObj",["count1","count2"]),...mapTargetValue("targetObj",{count1:"count3",count2:"count4"}),}
