浅谈vuex 闲置状态重置方案
前言
大型单页应用(后面都是指spa),我们往往会通过使用状态管理器vuex去解决组件间状态共享与状态传递等问题。这种应用少则几十个单页,多则上百个单页。随着路由的频繁切换,每个路由对应的vuex中的状态将越来越多。为了做到页面的极致优化,我们需要将那些闲置的状态重置,以减小占用的内存空间。
什么状态可以重置
vuex强调采用集中式存储管理应用的所有组件的状态,但是我们真把所有的状态都放到store中去处理,你会发现开发起来非常痛苦。这里如果想很好的把控哪些数据需要放到store中去管理,首先要理解vuex是用来解决什么问题的。vuex官网指出是为了解决多个组件共享状态的,那么我们就可以把多个组件的共享状态放到store中去管理,这里的多组件共享对于单页应用很多情况是跨路由的组件。如果store只存储多组件共享的状态,那么我们就没必要去清理vuex中的状态了,因为这些状态随时会被用到。
而随着业务场景越来越复杂,很多与后台交互的逻辑也都放到了组件中,这样代码就变得很凌乱,vuex也没有被充分利用。这时我们可以把与后台api交互的逻辑放到vuex中的action去处理,后台返回的状态自然也就放到了store管理。这样处理后,组件就只负责对数据进行渲染,逻辑非常清晰。而此时,组件对应的store中的状态随着路由的切换将会越来越多,而这些状态就需要我们手动的去清理了。
很多方案都有取舍,如果将与后台api交互的数据放到组件中,就没必要去清理了,但是代码逻辑将变得比较乱。另外诸如vuex的插件vue-devtools将无法监控到每次请求数据的变化...
什么时候去重置状态
我们想要的效果是在路由切换的时候,把上一个路由对应的vuex中的状态重置掉,但是路由和vuex并没有一一对应的关系,如果要做到这种效果,那么我们需要维护一个路由与vuex模块的对应关系,这样会很繁琐。不如当路由改变时去重置vuex中的所有状态。
vuex中闲置状态如何清理
下面将结合我的github实例去说明,这个实例创建了一个单页应用,我们通过切换路由的时候将闲置的状态清除。
改造路由对应组件的module状态
实例中采用拆分store为多个module的方式,将路由对应的组件状态放到对应的module中,多组件共享的状态放到顶级的store中管理。大致如下:
//store/index.js importpage1from"./modules/page1.js"; importpage2from"./modules/page2.js"; importpage3from"./modules/page3.js"; importpage4from"./modules/page4.js"; importpage5from"./modules/page5.js"; exportdefaultnewVuex.Store({ state, getters, actions, mutations, modules:{//每个路由对应的module page1, page2, page3, page4, page5 }, plugins:__DEV__?[createLogger()]:[], strict:__DEV__?true:false });
路由page1对应的module的state形如:
//store/modules/page1.js conststate={ //列表数据 page1Data:[], //标题数据 page1Title:'' }
这些数据是通过调用后端api返回并复制的数据,如果我们在路由改变的时候重置这些数据,那么需要将初始化数据提取出来,并且暴露一个需要重置的标识方法initState(),代表路由改变的时候需要重置,当然这个方法名称是个约定,你也可以定义为其他名称。改造后为:
//store/modules/page1.js //放置你要重置的数据 constinitState={ page1Data:[], } //state conststate={ //参数解构 ...initState, //路由改变不想重置的数据 page1Title:'', initState(){ returninitState } }
全局module配置
定义全局mutation事件类型
//store/types.js exportconstRESET_STATES='resetStates'
定义全局mutation
//store/mutation.js import*astypesfrom'./types' //检测所有的state并把`initState()`中的属性重置 functionresetState(state,moduleState){ constmState=state[moduleState]; if(mState.initState&&typeofmState.initState==='function'){ constinitState=mState.initState(); for(constkeyininitState){ mState[key]=initState[key]; } } } exportdefault{ [types.RESET_STATES](state,payload){ for(constmoduleStateinstate){ resetState(state,moduleState); } }, }
定义全局action
//store/action.js import*astypesfrom'./types' exportdefault{ //reststateaction resetStates:function(context,payLoad){ context.commit(types.RESET_STATES,payLoad); } }
路由切换触发重置方法
至此一切准备就绪,只需要在路由改变时触发重置的方法即可,在入口vue文件中处理
//components/app.vue
如果你的chrome浏览器安装了vuejs-devtools在路由切换的时候就能够很清晰的看到上一个路由数据的的重置过程。
总结
实例点这里。我们这里的vuex状态重置,是每次路由切换遍历所有的store中的状态,并把initState()中的属性重置,如果能做到把当前的路由对应的state重置就更好了,但是路由和store中的module并没有关联关系。这里只是提供一种重置vuex状态的一种方案,如果有更好方案还请各位看官留言。如有不妥的地方也欢迎拍砖留言。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。