Vue项目如何实现页面加载前跳转,避免已登录用户短暂显示登录页再重定向
问题根因
你当前的重定向逻辑写在组件beforeCreate生命周期中,但用户信息获取是异步操作,beforeCreate执行时GET_USER请求还未返回,store 里的用户id尚未赋值,此时判断逻辑不触发跳转。等异步请求完成、用户id更新后才触发跳转,此时页面已经开始渲染,就会出现0.5秒的可见闪烁。
解决方案
推荐按优先级选择以下方案:
方案1:将重定向逻辑移入中间件
中间件执行时机早于页面组件初始化,直接在异步请求完成后判断登录状态并跳转,可从根源避免页面渲染后再跳转的问题。
修改后的中间件代码如下:import {GET_CARD, GET_USER} from "../store/types/action-types"; export default async function ({store, redirect}) { // 无依赖的异步请求可并行发送,减少等待耗时 await Promise.all([ store.dispatch('cart/' + GET_CARD), store.dispatch('user/user/' + GET_USER) ]) // 登录状态符合条件直接跳转 if (store.state.user.user.id != null) { return redirect('/') } }同时可以删掉组件里写在
beforeCreate中的重定向逻辑。方案2:使用路由守卫做跳转判断
如果不需要全局中间件控制,可在对应路由的
beforeEnter守卫中处理重定向逻辑,路由守卫执行时机也早于组件渲染:// 路由配置文件 const routes = [ { path: '/login', // 你当前需要做重定向的页面路由 component: () => import('@/views/Login.vue'), async beforeEnter(to, from, next) { await store.dispatch('user/user/' + GET_USER) if (store.state.user.user.id != null) { next('/') return } next() } } ]方案3:增加加载状态遮罩
如果你确实需要把判断逻辑留在组件内,可以在用户信息加载完成前隐藏实际页面内容,避免展示页面元素:
<template> <!-- 仅用户信息加载完成且无需跳转时才展示页面内容 --> <div v-if="isUserLoaded && !needRedirect"> <!-- 原有页面内容 --> </div> </template> <script> export default { data() { return { isUserLoaded: false, needRedirect: false } }, async beforeCreate() { await this.$store.dispatch('user/user/' + GET_USER) this.isUserLoaded = true if (this.$store.state.user.user.id != null) { this.needRedirect = true this.$router.push('/') } } } </script>
内容的提问来源于stack exchange,提问作者m kh
相关产品推荐
相关产品推荐

