Vue-Router中间件配置问题:刷新子路由跳转至父路由
问题分析
刷新dashboard子路由后自动跳转到home的核心原因是页面刷新时Pinia Store初始化存在时序问题,路由钩子中token的初始值不准确,导致触发两次重定向:
- 刷新后Pinia Store初始化未完成,
token初始值为null/undefined,router.beforeEach检测到未登录,跳转到login login的前置钩子执行时,Store已完成初始化,token值已加载,因此又跳转到home
解决方案
- 移除路由文件中提前定义的
computedtoken,直接从Store获取最新值,避免时序问题 - 确保Auth Store同步从本地存储初始化token,保证路由钩子触发时token值准确
- 优化
router.beforeEach逻辑,等待用户信息加载完成后再执行权限判断 - 修正各路由前置钩子的取值方式,直接使用Store状态
修改后的代码
// Main Router const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/', name: 'index', component: LandingView, }, { path: '/login', name: 'login', component: LoginView, beforeEnter: (to, from, next) => { const authStore = useAuthStore(); if (authStore.token) { return next({ name: 'home' }); } next(); }, }, { path: '/signup/:uid?', name: 'signup', component: SignupView, }, { path: '/dashboard', name: 'dashboard', component: DashboardLayout, children: [ { path: '', name: 'home', component: HomeView, }, { path: 'profile', name: 'profile', component: ProfileView, }, { path: 'deposit', name: 'deposit', component: DepositView, }, { path: 'pay-amount/:amount?', name: 'pay-amount', component: PayAmountView }, { path: 'referral', name: 'referral', component: ReferralView, }, { path: 'salary', name: 'salary', component: SalaryView, }, ], meta: { requiresAuth: true, requiresEmailVerify: true, requiresPayment: true, requireKyc: true, }, }, { path: '/email-verify', name: 'email-verify', component: EmailVerifyView, meta: { requiresEmailVerify: false }, beforeEnter: (to, from, next) => { const authStore = useAuthStore(); if (!authStore.email) { next({ name: 'login' }); } next(); }, }, ], }); router.beforeEach(async (to, from, next) => { const authStore = useAuthStore(); const userStore = useUserStore(); const token = authStore.token; // 确保token存在且用户信息未加载时,等待获取完成 if (token && !userStore.user?.id) { try { await userStore.getUserDetails(); } catch (err) { // 处理请求失败,清除token并跳转登录 authStore.clearToken(); return next({ name: 'login' }); } } // 权限判断 if (to.meta.requiresAuth && !token) { return next({ name: 'login' }); } if (to.meta.requiresEmailVerify && userStore.user?.email_verified === false) { return next({ name: 'email-verify' }); } // 补充其他权限判断逻辑(示例) if (to.meta.requiresPayment && !userStore.user?.payment_done) { return next({ name: 'pay-amount' }); } if (to.meta.requireKyc && !userStore.user?.kyc_verified) { // return next({ name: 'kyc' }); // 若有KYC页面可开启 } next(); }); router.afterEach(() => { const {sidebarVisible, setSidebarVisible} = useLayoutStore(); if (sidebarVisible) { setSidebarVisible(false); } }); export default router;
额外注意事项
- 确保Auth Store同步从本地存储初始化token,示例:
export const useAuthStore = defineStore('auth', { state: () => ({ token: localStorage.getItem('token') || null, email: localStorage.getItem('email') || null }), // ...其他方法 }) - 异步获取用户信息时需捕获异常,避免因请求失败导致权限判断混乱
- 所有路由钩子中直接从Store取数,不要使用提前定义的响应式变量,保证数据实时性
内容的提问来源于stack exchange,提问作者Gursahb Webcyst
相关产品推荐
相关产品推荐

