利用Dectorator分模块存储Vuex状态的实现

  


  

  

在H5的Vue项目中,最为常见的当为单页应用(SPA),利用Vue-Router控制组件的挂载与复用,这时使用Vuex可以方便的维护数据状态而不必关心组件间的数据通信。但在Weex中,不同的页面之间使用不同的执行环境,无法共享数据,此时多为通过BroadcastChannel或存储模块来实现数据通信,本文主要使用修饰器(Decorator)来扩展Vuex的功能,实现分模块存储数据,并降低与业务代码的耦合度。
  

  

<强>
  

  

设计模式中有一种装饰器模式,可以在运行时扩展对象的功能,而无需创建多个继承对象。类似的,装饰可以在编译时扩展一个对象的功能,降低代码耦合度的同时实现多继承一样的效果。

  

<强> 2.1,Decorator安装
  

  

目前装饰还只是一个提案,在生产环境中无法直接使用,可以用babel-plugin-transform-decorators-legacy来实现。使用npm管理依赖包的可以执行以下命令:
  

        npm安装babel-plugin-transform-decorators-legacy - d   之前      

然后在.babelrc中配置
  

        {   “插件”:(   “transform-decorators-legacy”   ]   }   之前      

或者在webpack.config。js中配置
  

        {   测试:/\ . js/美元,   装载机:“babel-loader”,   选择:[   插件:[   需要.default (“babel-plugin-transform-decorators-legacy”)   ]   ]   }   之前      

这时可以在代码里编写装饰函数了。
  

  

<强> 2.2,装饰的编写
  

  

在本文中,装饰主要是对方法进行修饰,主要代码如下:
  装饰。js
  

        const actionDecorator=(目标、名称、描述符)=比;{   const fn=descriptor.value;   描述符。值=https://www.yisu.com/zixun/function (…args) {   console.log(“调用了修饰器的方法”);   返回fn。应用(这个,args);   };   返回描述符;   };   之前      

商店。js
  

        const模块={   状态:()=比;({}),   行动:{   @actionDecorator   someAction(){/* *业务代码* */},   },   };   之前      

可以看的到,actionDecorator修饰器的三个入参和Object.defineProperty一样,通过对module.actions.someAction函数的修饰,实现在编译时重写someAction方法,在调用方法时,会先执行console.log(“调用了修饰器的方法”);,而后再调用方法里的业务代码。对于多个功能的实现,比如存储数据,发送广播,打印日志和数据埋点,增加多个装饰即可。
  

  


  

  

Vuex本身可以用订阅和subscribeAction订阅相应的突变和行动,但只支持同步执行,而Weex的存储器存储是异步操作,因此需要对Vuex的现有方法进行扩展,以满足相应的需求。
  

  

<强> 3.1,修饰行动
  

  

在Vuex里,可以通过提交突变或者派遣行动来更改状态,而行动本质是调用提交突变。因为存储包含异步操作,在不破坏Vuex代码规范的前提下,我们选择修饰行动来扩展功能。
  

  

存储使用回调函数来读写项目,首先我们将其封装成承诺结构:
  

  

存储。js
  

        常量存储=weex.requireModule(存储);   常量处理程序={   得到:函数(目标,支撑){   const fn=目标(道具);//这里只需要用到这两个方法   如果([   “getItem”,   “setItem”   ]。一些(方法=比;方法===道具)){   返回函数(args) {//去掉回调函数,返回承诺   常量(回调)=args.slice (1);   const innerArgs=typeof调===δ堋? # 63;arg游戏。片(0,1):参数;   返回新的承诺((解决,拒绝)=比;{   fn。调用(目标,…innerArgs({结果、数据})=比;{   如果(结果==='成功'){   返回解决(数据);   }//防止模块无保存状态而出现报的错   返回解决(结果);   })   })   }   }   返回fn;   },   };   出口默认新代理(存储、处理程序);   之前      

通过代理,将setItem和getItem封装为承诺对象,后续使用时可以避免过多的回调结构。
  

  

现在我们把存储的setItem方法写入到修饰器:
  

  

装饰。js
  

利用Dectorator分模块存储Vuex状态的实现