前言

大型单页应用(后面都是指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
import page1 from "./modules/page1.js";
import page2 from "./modules/page2.js";
import page3 from "./modules/page3.js";
import page4 from "./modules/page4.js";
import page5 from "./modules/page5.js"; export default new Vuex.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
const state = {
// 列表数据
page1Data: [],
// 标题数据
page1Title: ''
}

这些数据是通过调用后端 api 返回并复制的数据,如果我们在路由改变的时候重置这些数据,那么需要将初始化数据提取出来,并且暴露一个需要重置的标识方法 initState(),代表路由改变的时候需要重置,当然这个方法名称是个约定,你也可以定义为其他名称。改造后为:


// store/modules/page1.js // 放置你要重置的数据
const initState = { page1Data: [],
} // state
const state = {
// 参数解构
...initState, // 路由改变不想重置的数据
page1Title: '', initState(){ return initState
}
}

全局 module 配置

定义全局 mutation 事件类型


// store/types.js
export const RESET_STATES = 'resetStates'

定义全局 mutation


// store/mutation.js import * as types from './types' // 检测所有的 state 并把 `initState()` 中的属性重置
function resetState(state, moduleState) { const mState = state[moduleState]; if (mState.initState && typeof mState.initState === 'function') { const initState = mState.initState(); for (const key in initState) { mState[key] = initState[key];
}
} } export default { [types.RESET_STATES](state, payload) { for (const moduleState in state) { resetState(state, moduleState);
}
}, }

定义全局 action


// store/action.js
import * as types from './types' export default {
// rest state action
resetStates:function (context, payLoad) { context.commit(types.RESET_STATES, payLoad);
}
}

路由切换触发重置方法

至此一切准备就绪,只需要在路由改变时触发重置的方法即可,在入口 vue 文件中处理


// components/app.vue
<script>
import {mapState, mapActions} from "vuex"
export default{ methods: { ...mapActions({
resetStates: "resetStates"
})
}, watch: { $route(to, from) {
// 路由改变发起重置
this.resetStates();
}
}
}
</script>

如果你的 chrome 浏览器安装了 vuejs-devtools 在路由切换的时候就能够很清晰的看到上一个路由数据的的重置过程。

总结

实例点这里。我们这里的 vuex 状态重置,是每次路由切换遍历所有的 store 中的状态,并把initState() 中的属性重置,如果能做到把当前的路由对应的 state 重置就更好了,但是路由和 store 中的 module 并没有关联关系。这里只是提供一种重置 vuex 状态的一种方案,如果有更好方案还请各位看官留言。如有不妥的地方也欢迎拍砖留言。

--完--

原文地址:https://segmentfault.com/a/1190000012686781

vuex 闲置状态重置方案的更多相关文章

  1. Redux/Mobx/Akita/Vuex对比 - 选择更适合低代码场景的状态管理方案

    近期准备开发一个数据分析 SDK,定位是作为数据中台向外输出数据分析能力的载体,前端的功能表现类似低代码平台的各种拖拉拽.作为中台能力的载体,SDK 未来很大概率会需要支持多种视图层框架,比如Vue2 ...

  2. vuex-- Vue.的中心化状态管理方案(vue 组件之间的通信简化机制)

    vuex-- Vue.的中心化状态管理方案(vue 组件之间的通信简化机制) 如果你在使用 vue.js , 那么我想你可能会对 vue 组件之间的通信感到崩溃 .vuex就是为了解决组件通信问题的. ...

  3. 理解vuex的状态管理模式架构

    理解vuex的状态管理模式架构 一: 什么是vuex?官方解释如下:vuex是一个专为vue.js应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证以一种可预测的 ...

  4. vuex 改变状态值得命名问题

    今天在做vuex的状态的时候 发现了个奇葩的问题,后面解决了,在改变状态的值得时候 传值的名称 不要和定义的状态的名称值相同,要不然会报错,如图所示 也就是password的名称不能相同,要不监测不到 ...

  5. (转)flutter 新状态管理方案 Provide (一)-使用

    flutter 新状态管理方案 Provide (一)-使用     版权声明:本文为博主原创文章,基于CC4.0协议,首发于https://kikt.top ,同步发于csdn,转载必须注明出处! ...

  6. Vuex 单状态库 与 多模块状态库

    之前对 Vuex 进行了简单的了解.近期在做 Vue 项目的同时重新学习了 Vuex .本篇博文主要总结一下 Vuex 单状态库和多模块 modules 的两类使用场景. 本篇所有代码是基于 Vue- ...

  7. 借鉴redux,实现一个react状态管理方案

    react状态管理方案有很多,其中最简单的最常用的是redux. redux实现 redux做状态管理,是利用reducer和action实现的state的更新. 如果想要用redux,需要几个步骤 ...

  8. Leetcode题目46.全排列(回溯+深度优先遍历+状态重置-中等)

    题目描述: 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], ...

  9. Vuex state 状态浅解

    对于Vuex中的state里面的理解总是有些欠缺,机制似乎理解了.但是还有很多的不足,在这就先浅谈下自己的理解. vuex 机制中,定义了全局Store,在各个vue组件面的this.$store指向 ...

随机推荐

  1. 线程进阶:多任务处理(17)——Java中的锁(Unsafe基础)

    在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...

  2. .NET框架详解

    .NET框架的战略目标 .NET框架的战略目标是在任何时候(When),任何地方(Where),使用任何工具(What)都能通过.NET的服务获得网络上的任何信息,享受网络带给人们的便捷和快乐! .N ...

  3. Sql Server创建主键失败:CREATE UNIQUE INDEX 终止,因为发现对象名称 '[PPR_BasicInformation]' 和索引名称 '[PK_PPR_BasicInformation]' 有重复的键(E)

    这种问题是由于主键设置了唯一性,而数据库中主键列的值又有重复的值,重复值为E,改掉其中一个值就可以了.

  4. Android 实现下拉刷新和上拉加载更多的RECYCLERVIEW和SCROLLVIEW

    PullRefreshRecyclerView.java /** * 类说明:下拉刷新上拉加载更多的RecyclerView * Author: gaobaiq * Date: 2016/5/9 18 ...

  5. 视图层 view

    视图层是 Django 处理请求的核心代码层,我们大多数 Python 代码都集中在这一层面.它对外接收用户请求,对内调度模型层和模版层,统合数据库和前端,最后根据业务逻辑,将处理好的数据,与前端结合 ...

  6. layui计算剩余时间

    <div id="test"></div> <script> layui.use('util', function(){ var util = ...

  7. NodeJS学习笔记 (4)网络服务-http(ok)

    原文:https://github.com/chyingp/nodejs-learning-guide 自己敲代码: http模块概览 大多数nodejs开发者都是冲着开发web server的目的选 ...

  8. tinymce原装插件源码分析(一)-hr

    tinymce简介 tinymce是一款能方便无限扩展的网页富文本编辑器. tinymce原装插件已经十分丰富,对于文本编辑(blog等文章)是绰绰有余,但是应对一些复杂的应用,比如在上面开发html ...

  9. 普通码农和CTO之间的差距

    虚心 学习的第一步是--"我不懂".一个空是水杯才能装水,如果是满的就没有办法装水了."自我肯定"是一种非常难克服的习惯,经常会有朋友看到某个技术或者实现之后不 ...

  10. iOS6和iOS7处理push不同之处,解决反复push,-(void) application: didReceiveRemoteNotification: fetchCompletionHandl

    如果读者已经知道push的基本知识,本文仅仅是解决一些适配,兼容问题.如果对push 不甚了解,參考以下的文章 1.[iOS push全方位解析](一) push的概述 2.[iOS push全方位解 ...