You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 21:46:06