Vue3页面刷新无法获取Vuex数据,跳转时正常的问题求助
解决Vuex刷新页面无法获取用户数据的问题
问题场景
登录后从 /login 跳转至个人主页 /me 时,能正常从Vuex Store拉取用户信息;但刷新 /me 页面时无法获取数据,控制台抛出错误。
控制台报错
runtime-core.esm-bundler.js:38 [Vue warn]: Unhandled error during execution of render function at <VCardTitle> at <VCard> at <VRow justify="center" > at <ProfilePage onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > at <RouterView> at <App> ... runtime-core.esm-bundler.js:38 [Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core at <VCardTitle> at <VCard> at <VRow justify="center" > at <ProfilePage onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > at <RouterView> at <App> ... ProfilePage.vue:6 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'toUpperCase') at ProfilePage.vue:6:63 at Proxy.renderFnWithContext (runtime-core.esm-bundler.js:847:21) at Proxy.<anonymous> (createSimpleFunctional.ts:22:10) at renderComponentRoot (runtime-core.esm-bundler.js:890:44) at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5602:57) at ReactiveEffect.run (reactivity.esm-bundler.js:185:25) at instance.update (runtime-core.esm-bundler.js:5716:56) at setupRenderEffect (runtime-core.esm-bundler.js:5730:9) at mountComponent (runtime-core.esm-bundler.js:5512:9) at processComponent (runtime-core.esm-bundler.js:5470:17)
相关代码(ProfilePage.vue)
<template> <nav-bar></nav-bar> <v-row justify="center"> <v-card> <v-card-title> {{ currentUser.first_name }} {{ currentUser.last_name.toUpperCase() }} </v-card-title> <v-card-text> {{ currentUser.description }} </v-card-text> </v-card> </v-row> </template> <script> import { computed } from "vue"; import { useStore } from "vuex"; export default { data() { return {}; }, setup() { const store = useStore(); return { currentUser: computed(() => store.getters.getUser), }; }, }; </script>
解决方案
1. 模板中添加空值保护
刷新页面时,Vuex Store会重置初始状态,currentUser 可能为 undefined 或 null,直接访问嵌套属性会触发报错。可以通过两种方式处理:
方式一:使用可选链操作符(ES2020+)
<v-card-title> {{ currentUser?.first_name }} {{ currentUser?.last_name?.toUpperCase() }} </v-card-title> <v-card-text> {{ currentUser?.description }} </v-card-text>
方式二:条件渲染,确保数据存在后再渲染
<v-row justify="center"> <v-card v-if="currentUser"> <v-card-title> {{ currentUser.first_name }} {{ currentUser.last_name.toUpperCase() }} </v-card-title> <v-card-text> {{ currentUser.description }} </v-card-text> </v-card> <!-- 可选:添加加载状态提示 --> <div v-else>加载中...</div> </v-row>
2. 实现Vuex状态持久化
刷新页面后Vuex状态会丢失,需要将用户信息持久化到本地存储(localStorage/sessionStorage),在Store初始化时恢复数据:
修改Vuex Store配置(示例):
const state = { // 初始化时从localStorage读取用户数据,无数据则设为null user: JSON.parse(localStorage.getItem('user')) || null }; const mutations = { SET_USER(state, userData) { state.user = userData; // 将用户数据存入localStorage localStorage.setItem('user', JSON.stringify(userData)); } }; const getters = { getUser: state => state.user };
3. 添加路由守卫,确保页面加载前数据就绪
在路由配置中添加全局前置守卫,进入 /me 页面时检查用户数据是否存在,不存在则从本地恢复或跳转至登录页:
import { useStore } from 'vuex'; router.beforeEach((to, from, next) => { if (to.path === '/me') { const store = useStore(); const savedUser = localStorage.getItem('user'); // 如果Store中无数据,但本地存储有,恢复到Store if (!store.getters.getUser && savedUser) { store.commit('SET_USER', JSON.parse(savedUser)); } // 如果本地也无数据,跳转至登录页 else if (!store.getters.getUser) { next('/login'); return; } } next(); });
内容的提问来源于stack exchange,提问作者Fares
相关产品推荐
相关产品推荐

