如何在服务端渲染应用中预加载含会话信息的Vuex Store
解决Vue SSR中无法访问localStorage的状态初始化问题
嘿,这个场景我太熟悉了!在Vue SSR环境里,服务端压根没有浏览器的localStorage API,直接在Store初始状态里调用它肯定会抛出错误。得从状态初始化时机和前后端状态同步两个方向来重构,具体步骤如下:
1. 先修改Store模块的初始状态,移除浏览器API依赖
把原来依赖localStorage的currentUser默认值改成服务端能安全处理的静态值(比如false),同时新增一个mutation用来后续更新这个状态:
export default { state: { // 服务端初始化时用默认值,后续在客户端或服务端预取时更新 currentUser: false, pending: false }, mutations: { [AUTH_ATTEMPT](state) { state.pending = true; }, // 新增mutation:专门用来设置currentUser状态 SET_CURRENT_USER(state, isAuthenticated) { state.currentUser = isAuthenticated; } }, // actions和其他代码保持不变 }
2. 在客户端入口文件中补全本地状态同步
客户端环境是有localStorage的,所以在挂载Vue实例之前,读取本地的token并更新Store:
// entry-client.js(你的客户端入口文件) import { createApp } from './app'; const { app, store } = createApp(); // 只在客户端环境执行:读取localStorage并更新状态 if (typeof window !== 'undefined') { const hasValidToken = !!localStorage.getItem('token'); store.commit('SET_CURRENT_USER', hasValidToken); } // 最后挂载应用 app.$mount('#app');
3. (可选)服务端预取用户状态(如果需要)
如果你的JWT是存在Cookie里的(服务端能拿到请求头),可以在服务端入口文件中提前解析请求,初始化用户状态,这样服务端渲染的页面就能直接带上用户状态:
// entry-server.js(你的服务端入口文件) import { createApp } from './app'; export default context => { return new Promise((resolve, reject) => { const { app, store } = createApp(); // 从请求的Cookie中获取token(假设你的Cookie键名是token) const token = context.req.cookies?.token; if (token) { // 这里可以额外调用接口验证token有效性,再更新状态 store.commit('SET_CURRENT_USER', true); } resolve(app); }); };
核心思路总结
SSR的状态要遵循服务端初始化基础状态,客户端同步本地状态的原则:服务端只能处理和请求相关的状态(比如Cookie),浏览器专属API(localStorage/sessionStorage)必须放到客户端初始化阶段执行,这样才能避免服务端报错,同时保证前后端状态一致。
内容的提问来源于stack exchange,提问作者Marc Fletcher
相关产品推荐
相关产品推荐

