在 vue-cli 中,使用VueX,并解决刷新state数据丢失问题

1. NPM安装

npm install vuex --save

官网推荐安装 es6-promise
官方解释:如果你支持的浏览器并没有实现 Promise (比如 IE),那么你可以使用一个 polyfill 的库,例如 es6-promise

npm install es6-promise --save

2.在 src 文件夹下新建 store 文件夹,并在新建的 store 文件夹下新建以下几个文件夹

  1. state.js 文件夹
export default {
  msg: 0,
}
  1. mutations.js 文件夹
export default {
  mutationsAdd(state) {
    state.msg++
  },
}

这个 js 中处理同步数据
在页面的 methods 的方法中使用 this.$store.commit('mutationsAdd') 调用

  1. actions.js 文件夹
export default {
  actionsAdd(context) {
    setTimeout(() => {
      context.commit('mutationsAdd')
    }, 1000);
  },
}

这个 js 中处理异步数据
在页面的 methods 的方法中使用 this.$store.dispatch('actionsAdd') 调用

  1. getters.js 文件夹
export default {
  doneTodos(state) {
    if (state.msg >= 5) {
      state.msg = 0;
      return state.msg
    } else {
      return state.msg
    }
  }
}

这个 js 处理状态,进行数据过滤,
在页面的 template 中使用 {{ $store.getters.doneTodos }} 渲染

  1. index.js 文件夹
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import actions from './actions'
import mutations from './mutations'
import getters from './getters'

Vue.use(Vuex);
export default new Vuex.Store({
  state: state,
  actions: actions,
  mutations: mutations,
  getters: getters
});

假如按官方推荐安装了 es6-promise ,那么在 index.js 中还需要添加

import 'es6-promise/auto'

3.在 main.js 中添加

import store from './store'

并同 router 一样,需要注入

new Vue({
  el: '#app',
  router, 
  store,
  components: {App},
  template: ''
});

4.当然,这之间也可以传值,不过只能传一个值,数据格式不限

  1. 页面方法中调用
this.$store.dispatch('actionsAdd', {a: 4, b: 3})
  1. actions.js
export default {
  actionsAdd(context,data) {
    setTimeout(() => {
      context.commit('mutationsAdd',data)
    }, 200);
  },
}
  1. mutations.js
export default {
  mutationsAdd(state, data) {
    state.msg = data.a
  },
}

5.VueX中的数据在页面刷新时会丢失问题

  1. 可以在 App.js 的 created 生命周期中添加
      if (sessionStorage.getItem("store")) {
        this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))));
        sessionStorage.removeItem('store')
      }
      window.addEventListener("beforeunload", () => {
        sessionStorage.setItem("store", JSON.stringify(this.$store.state))
      });

6. 换一种写法

新建keepState.js文件

import store from '../store/store.js';
export function keepState(){
    /* 
    *tips:不能使用localStroge,否则关闭页面后,localStroge中的state不会删除,导致下次打开页面的时候还是上次的state
    */
    if(!arguments.length){
        //不传参数,调用
        keepStateAll()
    }else{
        //传参数调用
        keepStatePart(arguments[0]);
    }
} 
export function keepStateAll() {
    //刷新页面,保留所有的state
    if (sessionStorage.hasOwnProperty("store")) {
        store.replaceState(
            Object.assign(
                {},
                store.state,
                JSON.parse(sessionStorage.getItem("store"))
            )
        );
        sessionStorage.removeItem("store");
    }
    window.addEventListener("beforeunload", () => {
        sessionStorage.setItem("store", JSON.stringify(store.state));
    });
}
export function keepStatePart(args) {
    /*
    **刷新页面保留部分state
    **args [] state的名称
    */
    let keepStateList = [];
    let sessionState = {};
    //筛选需要保存的state是否存在
    args.forEach((stateKey) => {
        if (!store.state.hasOwnProperty(stateKey)) {
            console.warn('store中没有:' + stateKey + ',请确认')
        } else {
            keepStateList.push(stateKey)
        }

    })
    //从sessionStroge中读取保存的state
    keepStateList.forEach((stateKey) => {
        if (sessionStorage.hasOwnProperty(stateKey)) {
            sessionState[stateKey] = JSON.parse(sessionStorage.getItem(stateKey))
        }
    })
    //合并store中的state
    store.replaceState(
        Object.assign(
            {},
            store.state,
            sessionState
        )
    );
    //合并store的state后,删除sessionStroge中的state
    keepStateList.forEach((stateKey)=>{
        sessionStorage.removeItem(stateKey);
    })
    //监听页面加载前,将store中的state存到sessionStroge中
    window.addEventListener("beforeunload", () => {
        keepStateList.forEach((stateKey) => {
            sessionStorage.setItem(stateKey, JSON.stringify(store.state[stateKey]));
        })
    });
}

在APP.vue 中引入

import { keepState } './keepState'

同时,在created中调用keepState(),此方法可以传参,传参表示想保留state中的某一项或者某几项的值(传参类型为数组)

你可能感兴趣的:(在 vue-cli 中,使用VueX,并解决刷新state数据丢失问题)