Appearance
Vuex 数据持久化解决方案
背景痛点
- 用户登录信息通常存储在 Vuex 中实现跨组件通信
- 页面刷新时 Vuex 状态会重置,导致登录信息丢失
- 手动同步状态到 Storage 方案不够智能且维护成本高
解决方案:自定义 Vuex 插件
1、利用 Vuex 插件机制:
- 插件在 Vuex 初始化时执行,接收 store 实例
- 通过订阅机制监听状态变化,将状态变化同步到 Storage
(store.subscribe)
2、状态持久化流程:
- 初始化& 刷新页面时,从 Storage 读取状态并替换 Vuex 状态
(store.replaceState)
- 状态变更时自动保存到 Storage
- 初始化& 刷新页面时,从 Storage 读取状态并替换 Vuex 状态
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) });
// ...