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