Skip to content

Vuex 数据持久化解决方案

背景痛点

  • 用户登录信息通常存储在 Vuex 中实现跨组件通信
  • 页面刷新时 Vuex 状态会重置,导致登录信息丢失
  • 手动同步状态到 Storage 方案不够智能且维护成本高

解决方案:自定义 Vuex 插件

  • 1、利用 Vuex 插件机制:

    • 插件在 Vuex 初始化时执行,接收 store 实例
    • 通过订阅机制监听状态变化,将状态变化同步到 Storage(store.subscribe)
  • 2、状态持久化流程:

    • 初始化& 刷新页面时,从 Storage 读取状态并替换 Vuex 状态(store.replaceState)
    • 状态变更时自动保存到 Storage
js
function statePersistence ( store ) {
  const localState = sessionStorage.getItem( 'VUEX_STATE' );
  if ( localState ) {
    // store.replaceState( JSON.parse( localState ) );
    store.replaceState({ ...toRaw(store.state), ...JSON.parse(localState) })

  }
  store.subscribe( ( { type }, state ) => {
    sessionStorage.setItem( 'VUEX_STATE', JSON.stringify( state ) );
  } )
}

const store = createStore( {
  plugins: [ statePersistence ]}
  ....
)

问题与思考

  • 问题?

    • 同事加了一个新的 store 模块,直接刷新页面时,取新模块 State 数据报错,找不到该模块
  • 原因

    • 我们自己写了一个 vuex 持久化插件,当页面刷新的时候,我们会把持久化的数据,去替换 Root.State
    • 由于是新的模块,此时又没有新的mutations提交,导致持久化的时候没有存储新的模块,直接取值会导致找不到该模块
  • 思考

    • 页面在刷新的时候,获取到新的 State,和持久化的 State 数据,进行合并
js
// ...
store.replaceState({ ...toRaw(store.state), ...JSON.parse(localState) });
// ...