在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状态的实现