vuex刷新后丢失原因和解决办法

原因:
  1. vuex存储的数据只是在页面中,相当于全局变量,页面刷新时vuex里的数据会重新初始化,导致数据丢失
  2. vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据会被重新赋值
解决思路:
  1. 将vuex的数据直接保存在浏览器的缓存中(sessionStorage、localStorage、cookie)
  2. 页面刷新后再从浏览器中取出
解决方法一:
  1. 选择合适的浏览器存储

    localStorage – 永久存储在本地,除非主动删除

    sessionStorage – 存储在当前tab页,关闭当前tab页就会消失

    cookie – 根据设置的有效时间来存储,缺点是内存小不能存储大数据且不易读取,会和后台进行交互

    注:一般vue会选择sessionStorage,因为一是vue是单页面应用,操作都是在一个页面跳转路由,二是可以保证打开页面时,sessionStorage的数据为空,而如果是localStorage则会读取上一次打开页面的数据

  2. 页面刷新的时候,监听浏览器刷新前事件,在浏览器刷新之前就把vuex里的数据保存到sessionStorage中,刷新成功后如果异步请求的数据未返回则直接获取sessionStorage的数据

解决方法二:

Vuex持久化插件(vuex-persistedstate)

  1. 原理:将vuex的state存在浏览器存储中一份,刷新页面的 一瞬间,vuex数据消失,会去浏览器存储中拿回数据

  2. 使用方法:

    • 目的:让在vuex中管理的状态数据同时储存在本地。可免去自己储存的环节。

    • 适用场景:

      a:在开发的过程中,像用户信息(名字,头像,token)需要vuex中储存且需要本地储存

      b:购物车如果需要未登录状态下也支持,如果管理在vuex中页面需要储存在本地

    • 使用步骤:

      1. 安装vuex的插件vuex-persistedstate来支持vuex的状态持久化

        npm i vuex-persistedstate
        
      2. 在store文件夹下新建modules文件,在modules下根据项目创建模块化js

      3. 在index.js文件中引入模块化的js,使用vuex-persistedstate插件对想存储的模块来进行持久化

        // 以下代码为我其中一项目中的,可根据自己项目中的自行更改适配
            import Vue from 'vue'
            import Vuex from 'vuex'
            import createPersistedState from 'vuex-persistedstate'
            import getters from './getters'
            import $config from '@/config'
        
            Vue.use(Vuex)
        
            // https://webpack.js.org/guides/dependency-management/#requirecontext
            const modulesFiles = require.context('./modules', true, /\.js$/)
        
            // 自动引入modules目录下的vuex模块
            const modules = modulesFiles.keys().reduce((modules, modulePath) => {
              const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
              const value = modulesFiles(modulePath)
              modules[moduleName] = value.default
              return modules
            }, {})
            const store = new Vuex.Store({
              getters,
              modules,
              strict: process.env.NODE_ENV !== 'production',
            	// 如果此刻想配置多个选项,将plugins写成一个一维数组,不然会报错。
              plugins: [
                // 可以有多个持久化实例
                createPersistedState({
                  key: `wyx-${$config.PLATFORM}`, // 状态保存到本地的 key
                  paths: ['app.pageTab', 'common.menuInfo', 'aliyunOss', 'common.noviceDerverInfo', 'common.shopStatus', 'common.shopDetailData', 'app.marketingTab', 'addEditGoods.checkCycleList'], // 要持久化的状态,在state里面取
                  storage: { // 存储方式定义
                    getItem: (key) => localStorage.getItem(key), // 获取
                    setItem: (key, value) => localStorage.setItem(key, value), // 存储
                    removeItem: (key) => localStorage.removeItem(key) // 删除
                  }
                })
              ]
            })
        
            export default store
        

参数说明:

createPersistedState([options])使用给定的选项创建插件的新实例。可以提供以下选项来配置您的特定需求的插件:

key :存储持久状态的键。(默认:vuex)

paths :部分持续状态的任何路径的数组。如果没有路径给出,完整的状态是持久的。(默认:[])

reducer :一个函数,将被调用来基于给定的路径持久化的状态。默认包含这些值。

subscriber :一个被调用来设置突变订阅的函数。默认为store => handler => store.subscribe(handler)

storage :而不是(或与)getState和setState。默认为localStorage。

getState :将被调用以重新水化先前持久状态的函数。默认使用storage。

setState :将被调用来保持给定状态的函数。默认使用storage。

filter :将被调用来过滤将setState最终触发存储的任何突变的函数。默认为() => true

解决方法三:

插件vuex-along

原理同vuex-persistedstate

使用:

import Vue from 'vue';
import Vuex from 'vuex';
import createVuexAlong from "vuex-along";

const moduleA = {
  state: {
    a1: "hello",
  }
};

const store = new Vuex.Store({
  state: {
    count: nll
     token:''",
  },
  mutations: {
    set_count: (state, payload) => {
      state.count= payload
    },
    set_token: (state, payload) => {
      state.token = payload
    },
  plugins: [
    createVuexAlong({
      name: "hello-vuex-along", // 设置保存的集合名字,避免同站点下的多项目数据冲突
      local: {
        list: ["ma"],
        isFilter: true // 过滤模块 ma 数据, 将其他的存入 localStorage
      },
      session: {
        list: ["count", "ma.a1"] // 保存 count 和模块 ma 中的 a1 到 sessionStorage
      }
      //如果对于sessionstorage不进行任何操作,也可将session设为false
    })
  ]
});


参数说明:

VuexAlongOptions

字段 必选 类型 描述
name string 设置本地数据集合的名字,默认为vux-along
local Object localStorage的配置,见WatchOptions表格
session Object sessionStorage的配置,见WatchOptions表格
justSession Boolean 仅使用sessionStorage

WatchOptions

字段 必选 类型 描述
list String[] 需要监听的属性名或模块名的字符串列表
isFilter Boolean 过滤list中的字段,而非保存

注:list的四种写法


// 什么都不缓存
{
    list: [ '' ],   
}   
// 全部缓存
{
    list: [  ],   
}   
//  指定缓存
{
    list: [ 'user' ],   
}
// 除了这几个,其他的都缓存
{
 list: [ 'user', 'class' ], 
 isFilter: true
}

数据清理:

window.clearVuexAlong(local = true, session = true):void;
clearVuexAlong() // localStorage 和 sessionStorage 都会被清理
clearVuexAlong(true,false) // 只清理 localStorage
clearVuexAlong(false,true) // 只清理 sessionStorage

你可能感兴趣的:(vue,javascript,前端,vue.js)