1、问题原因
Vuex 是 Vue 的状态管理工具,其数据只存储在内存中。当用户刷新页面时,Vue 实例会被重新加载,Vuex 中的 state 状态也会被重置为初始值。
2、解决方案
为了解决刷新后数据丢失的问题,可以将数据同步存储在 浏览器的本地存储 中,如:
localStorage
sessionStorage
cookie(不推荐用于大数据)
1)手动使用 localStorage 或 sessionStorage 持久化
监听页面刷新事件,在 beforeunload
或 watch
中将 Vuex 的 state 保存到本地存储。页面重新加载时,判断本地存储是否存在已保存的 state,如果存在则恢复。
// main.js
const savedState = JSON.parse(localStorage.getItem('storeState'))
if (savedState) {
store.replaceState(Object.assign(store.state, savedState))
}
window.addEventListener('beforeunload', () => {
localStorage.setItem('storeState', JSON.stringify(store.state))
})
2)使用第三方插件自动持久化
vuex-persistedstate
是最常用的 Vuex 状态持久化插件。自动同步 Vuex 状态到本地存储,支持局部存储、自定义 key、加密等。
安装:
npm install vuex-persistedstate
// store/index.js
import createPersistedState from 'vuex-persistedstate'
const store = new Vuex.Store({
state: { ... },
mutations: { ... },
plugins: [createPersistedState({
storage: window.sessionStorage // 可改为 localStorage
})]
})
Pinia 是 Vue 3 的官方状态管理库,专为 Composition API 和模块化架构而设计,是 Vuex 的继任者。从 Vue 3 起,官方推荐使用 Pinia 代替 Vuex,它可以结合插件 pinia-plugin-persistedstate
实现类似功能。
安装:npm install pinia-plugin-persistedstate
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
name: 'Pinia'
}),
actions: {
increment() {
this.count++
},
reset() {
this.count = 0
}
},
// 👇 开启持久化
persist: true
})
Pinia 高级配置(指定 key、选择字段、存储方式):
persist: {
key: 'my-counter', // 存储在 localStorage 中的 key 名
storage: sessionStorage, // 默认为 localStorage
paths: ['count'] // 指定需要持久化的字段(可选)
}
3、本地存储方式对比
存储方式 | 是否持久 | 适用场景 | 数据大小限制 | 有效期 |
localStorage | ✅ | 长期保存用户信息 | ~5MB | 永久(除非主动清除) |
sessionStorage | ❌ | 页面刷新后恢复状态 | ~5MB | 页面关闭后失效 |
cookie | ⚠️有限 | 简单登录状态、跨页共享 | ~4KB | 可设定失效时间 |
注意:cookie 区分域但不区分端口,适合小数据和服务器通信场景;而 localStorage 和 sessionStorage 更适合前端持久化状态。
刷新页面导致 Vuex 状态丢失,是因为其默认行为不具备持久化机制。根据业务需要,可以选择
轻量场景 → 使用 sessionStorage
长久保存 → 使用 localStorage
更自动的方式 → 使用 vuex-persistedstate 插件或升级至 Pinia