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 中管理。大体以下:php

// 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 形如:vue

// store/modules/page1.js
const state = {
     // 列表数据
     page1Data: [],
     // 标题数据
     page1Title: ''
}

这些数据是经过调用后端 api 返回并复制的数据,若是咱们在路由改变的时候重置这些数据,那么须要将初始化数据提取出来,而且暴露一个须要重置的标识方法git

initState()

,表明路由改变的时候须要重置,固然这个方法名称是个约定,你也能够定义为其余名称。改造后为:github

// store/modules/page1.js

// 放置你要重置的数据
const initState = {

    page1Data: [],
}

// state
const state = {
    // 参数解构
    ...initState,

    // 路由改变不想重置的数据
    page1Title: '',

    initState(){

        return initState
    }
}

全局 module 配置 定义全局 mutation 事件类型vuex

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

定义全局 mutationchrome

// 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);
        }
    },

}

定义全局 actionsegmentfault

// 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 中的状态,并把api

initState()

中的属性重置,若是能作到把当前的路由对应的 state 重置就更好了,可是路由和 store 中的 module 并无关联关系。这里只是提供一种重置 vuex 状态的一种方案,若是有更好方案还请各位看官留言。若有不妥的地方也欢迎拍砖留言。
--完--
原文地址:https://segmentfault.com/a/11...
转载于猿2048:▶《vuex 闲置状态重置方案》浏览器

相关文章
相关标签/搜索