解决进入主页面动态权限菜单未显示和页面刷新白屏或路由404页面问题

文章主要讨论了登录成功后主界面菜单列表有时不显示的问题,原因是动态权限菜单未获取。提出三种解决方案,包括使用定时器、计算属性和Promise处理。此外,还分析了页面刷新导致的白屏和404问题,因动态路由丢失。提出了两种解决办法,如在App.vue中重新请求菜单或全局路由拦截。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.解决登录成功跳转到主界面有时主界面菜单列表不显示问题

1.原因分析:在登陆进入主页面时,动态权限菜单并未获取到,导致无法显示。

2.解决问题:

   方法一:在跳转到主页面时,对跳转的代码设置定时器

  setTimeout(() => {
                        this.$router.push({path: '/home'}) 
                    }, 2000);

  方法二:将接受的动态权限菜单的改为computed计算属性接收

  

 computed: {
        menuList() {
            // 动态路由权限列表
            return this.$store.getters['menu/menu']
        },
    },

方法三:使用promise对象在请求菜单权限接口完成,并动态添加路由后再跳转到主页面

// 登录:
// 电泳动态权限菜单并动态创建路由的方法
this.$store.dispatch('menu/save_menu', resultInfo.role_id).then(() => {
   ElMessage.success('登录成功')
   this.$router.push({path: '/home'})
})

// store中的方法,获取动态权限菜单并动态创建路由
actions: {
     save_menu({commit}, roleId) { // roleId 角色id
          // 解决办法:返回一个promise对象
          return new Promise(async (resolve, reject) => { 
              const data = await RquestSystemMenus(roleId) // roleId 角色id
              const { resultCode, resultInfo } = data
              if(resultCode === 1) {
                  const menulist = useMenu(resultInfo)
                  // 使用路由的实例(router)的addRoute动态添加路由,参数一:要添加的路由记录
                  menulist.forEach(route => router.addRoute(route))
                  commit('SAVE_MENU', menulist)
                  resolve()
              } else {
                  ElMessage.error(resultInfo)
                  reject()
              }
          })
      }
  },

2.页面刷新白屏问题或找路由404页面问题原因分析?

1.由于刷新页面,页面重新加载(重新加载整个程序),从入口文件main.js和根组件App.vue执行,路由会被初始化,初始化后动态添加的路由会丢失。导致无法找到动态添加的路由,从而出现白屏和404页面问题

2.路由对应的组件是动态添加的 router.addRoute(route) ,在登录成功时获取权限菜单格式化后动态添加

3.虽然我们将权限菜单的数据保存到store,并做了持久化存储到localStorage,但是对象是不能持久化存储的会报错,component组件对象刷新界面后丢失

3.解决办法:

登录时保存角色的id

方法一:在App.vue组件中再次动态请求权限菜单接口,动态添加路由,再次跳转当前路由。注意:在路由跳转时,因为接口是异步的,同时执行代码的话会导致路由跳转时动态路由并未添加,还会出现白屏问题。解决办法:在接口的回调中跳转(不推荐),推荐方法:返回一个promise对象,在then方法中跳转路由

方法二:在全局路由导航中,对所有路由进行拦截,再次动态请求权限菜单接口,动态添加路由,再次跳转当前路由(不推荐,在接口未响应的这段时间,全局前置路由可能有拦截多次,导致再次请求权限菜单接口)

方法一:

方法二:

### Vue3 动态路由页面刷新白屏解决方案 在 Vue3 项目中,动态路由可能会因为页面刷新而导致白屏问题。以下是针对该问题的详细分析与解决方案。 #### 1. 原因分析 当用户访问某个带有动态路由页面时,如果提前加载对应路由信息,则可能导致 `router` 配置全,在刷新页面时无法找到对应路径从而引发白屏现象[^1]。此外,Vue Router 的初始化逻辑也会影响最终效果,因此需要特别关注路由注册时机以及缓存机制。 --- #### 2. 解决方案一:预加载动态路由并存储于本地缓存 为了防止刷新导致丢失数据的情况发生,可以在应用启动阶段预先拉取后台返回的所有可用菜单及其关联的前端组件地址,并将其保存下来以便后续重复利用: - **实现步骤** - 在入口文件(如 main.ts app.vue)处调用服务端 API 接口获取完整的权限列表; - 将这些数据序列化成字符串形式并通过 sessionStorage/localStorage 存储起来; - 创建一个新的函数用于解析已有的静态+动态组合后的完整 route tree 结构体; ```typescript // permissionHelper.ts import { RouteRecordRaw } from 'vue-router'; function loadDynamicRoutes(): Array<RouteRecordRaw> { const cachedMenusStr = window.sessionStorage.getItem('dynamic-routes'); if(cachedMenusStr){ return JSON.parse(cachedMenusStr); } throw Error("No dynamic routes found!"); } export default loadDynamicRoutes; ``` 随后修改原有 router/index.ts 文件如下所示: ```typescript const loadedRoutes = loadDynamicRoutes(); const constantRoutes: RouteRecordRaw[] = [ //...your static routes here... ]; let allRoutes = [...constantRoutes,...loadedRoutes]; const router = createRouter({ history:createWebHistory(), routes:allRoutes, }); ``` 这样即使浏览器重新载入网页也会再次触发网络请求过程而是直接采用之前保留下来的副本继续渲染视图层结构. --- #### 3. 方案二:基于 addRoute 方法实时更新路由表 另一种更灵活的方式则是借助 vue-router 提供的 api 来完成按需懒加载式的功能扩展操作——每当检测到新的子模块被激活之后再即时追加相应的节点进去即可满足需求. 具体做法可以参照下面这段伪代码片段演示如何结合 vuex 状态管理工具来达成目标 : ```javascript // store/modules/auth.js async function fetchUserPermissions({commit}){ const resp=await axios.get('/api/user/permissions'); commit('setPermissionList',resp.data.permissions); } actions:{ async initializeApp(context,payload){ await context.dispatch('fetchUserPermissions'); payload.next(); // allow navigation to proceed after permissions are set. }, } mutations:{ setPermissionList(state,value){ state.permissionList=value.map(item=>convertToRouteObject(item)); applyNewlyAddedRoutes(state.permissionList); // helper func defined elsewhere. } } // utils/routeUtils.js function convertToRouteObject(permissionItem){ return {...}; } function applyNewlyAddedRoutes(newRoutesArray){ newRoutesArray.forEach(route=>{ router.addRoute(route.parentName||'',route); }); } ``` 以上策略允许我们在影响整体性能表现的前提下逐步完善整个系统的导航体系架构设计[^2], 同样适用于大型复杂的企业级应用场景当中 . --- #### 4. 补充注意事项 无论采取哪种办法都需要注意以下几点事项 : - 确认首页本身属于固定变的部分而非依赖外部条件决定的内容 ; - 如果存在通配符类型的兜底规则的话记得同样作为独立实体加入进来以免遗漏某些特殊情况下的处理流程 ; - 对异常情况进行妥善捕获反馈给终端使用者友好提示消息而是简单粗暴地终止程序运行 ; 最后提醒大家务必测试清楚各种边界情况才能放心上线部署哦 ! ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值