为什么Nuxt中间件触发Vuex Mutation后仍获取不到更新后的Store状态?
问题原因
vuex-persistedstate 默认使用浏览器的 localStorage 存储状态,该存储仅客户端可访问,且状态恢复时机晚于中间件执行时机:
- 如果是 SSR/SSG 场景,服务端运行中间件时完全无法读取客户端 localStorage 数据,且如果你的持久化插件设置了仅客户端运行,服务端侧永远不会执行状态恢复逻辑,拿到的始终是 state 初始值
- 如果是纯 SPA 场景,中间件执行时持久化插件还未完成状态回写,读到的也是初始值
解决方案
场景1:纯客户端SPA项目
调整逻辑执行时机即可:
- 将读取 state 的逻辑从中间件移到页面
mounted生命周期,或者路由afterEach守卫中,此时持久化插件已经完成状态恢复 - 调整插件注册顺序,确保 vuex-persistedstate 插件在中间件相关逻辑之前加载
场景2:Nuxt SSR/SSG项目
按实际需求选择方案:
需求1:仅客户端需要用到该状态
在中间件中增加客户端运行判断,仅在客户端侧执行读取逻辑:
// middleware/authenticated.js export default function ({ store, process }) { if (process.client) { // 此时已完成持久化状态恢复,可拿到正确值 console.log(store.state.truthy) } }
需求2:服务端也需要读取该状态
将持久化存储介质更换为 cookie,cookie 会随请求自动发送到服务端,两端都可正常读写:
安装依赖
npm install js-cookie修改持久化插件配置
// plugins/persistedstate.js import createPersistedState from 'vuex-persistedstate' import Cookies from 'js-cookie' export default ({ store, req }) => { createPersistedState({ // 自定义存储逻辑,两端统一用cookie读写 storage: { getItem: (key) => { if (process.server) { // 服务端从请求头解析cookie const cookieStr = req.headers.cookie || '' const targetCookie = cookieStr.split(';').find(c => c.trim().startsWith(`${key}=`)) return targetCookie ? decodeURIComponent(targetCookie.split('=')[1]) : null } // 客户端直接读本地cookie return Cookies.get(key) }, setItem: (key, value) => Cookies.set(key, value, { expires: 7 }), removeItem: (key) => Cookies.remove(key) } })(store) }
- 检查
nuxt.config.js插件配置,确保没有加客户端运行限制:
// nuxt.config.js export default { plugins: [ '~/plugins/persistedstate.js' // 不要加mode: 'client'配置 ] }
修改完成后无论服务端还是客户端运行中间件,都能读取到正确的持久化状态。
内容的提问来源于stack exchange,提问作者Karioki Z
相关产品推荐
相关产品推荐

