首页 前端知识 解决vue3,动态添加路由,刷新页面出现白屏或者404

解决vue3,动态添加路由,刷新页面出现白屏或者404

2025-02-24 13:02:05 前端知识 前端哥 282 25 我要收藏

解决vue3,动态添加路由,刷新页面出现白屏或者404

1.解决出现刷新页面,出现404的情况

1.问题的出现

在做毕设的时候,在权限路由得到时候,我问通过router**.**addRoute(item)的方式,在路由守卫动态添加路由

刚开始没什么问题,页面的都能正常显示,网络请求也能发送,后来出现了刷新页面,跳转到404

原因:没有将404路由进行动态的添加,而是将他放到了静态路由表里,这就会导致动态的路由会出现404后面,匹配动态路由的时候

上错误代码:


routes = [
  {
    path: '/',
    redirect: '/login',
    hidden: true
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/views/Login/index.vue'),
    hidden: true
  },
  {
    path: '/register',
    name: 'register',
    component: () => import('@/views/Register/index.vue'),
    hidden: true
  },
  // 首页
  {
    path: '/home',
    name: 'home',
    component: Layout,
    redirect: '/home/index',
    children: [
      {
        path: 'index',
        meta: {
          title: '首页',
          icon: 'HomeFilled'
        },
        component: () => import('@/views/home/index.vue')
      }
    ]
  },
  {
    path: '/personal',
    name: 'personal',
    component: Layout,
    children: [
      {
        path: 'userinfo',
        meta: {
          title: '个人信息'
        },
        component: () => import('@/views/Personal/userinfo.vue')
      },
      {
        path: 'password',
        meta: {
          title: '修改密码'
        },
        component: () => import('@/views/Personal/password.vue')
      }
    ]
  }//404
   {
  path: '/:cachAlll(.*)',
  component: () => import('@/components/common/404.vue'),
  hidden: true
}
]

解决方法

  1. 提取出404代码片段

    const cachAlll = {
      path: '/:cachAlll(.*)',
      component: () => import('@/components/common/404.vue'),
      hidden: true
    }
    
  2. 追加到处理好的权限列表的末尾

    筛选出用户的权限路由函数,后来发现我的这种方法有点笨

    `

 /**
    * 用户权限认证
    */
   const permission = userStore.userInfo.permission
   
   function permissionAuth(data) {
     return permission?.includes(data)
   }
   
   
   
   function hasPermission(data) {
     let homeMenu = []
     data.forEach((item) => {
       //有permission的路由才做判断,没有的直接放进数组
       if (item.permission && !item.children) {
         if (permissionAuth(item.permission)) {
           homeMenu.push(item)
         }
       } else if (item.permission && item.children) {
         let obj = {}
         if (permissionAuth(item.permission)) {
           obj = {
             ...item,
             children: []
           }
           item.children.forEach((child) => {
             if (permissionAuth(child.permission)) {
               obj.children.push(child)
             }
           })
         }
         // 判断obj是否为空
         if (obj.router) {
           homeMenu.push(obj)
         }
       } else {
         homeMenu.push(item)
       }
     })
     return homeMenu
   }
//router/index.js 
let filterRouter = hasPermission(asyncRouter)
  filterRouter.push(cachAlll)

   我项目采用的vue-router是4.3.3版本

   ```js
   //路由前置守卫
   router.beforeEach(async (to, from) => {
     console.log('路由前置守卫')
   
     const userStore = useUserStore()
     const token = userStore.token
     // 1.在白名单
     if (whiteList.includes(to.path)) {
       return true
     }
     // 2.不在白名单
     if (!whiteList.includes(to.path) && !token) {
       console.log('不在白名单')
       return '/login'
     }
     // 3.有token
     if (token) {
       // 3.1.判断有没有用户信息
       if (JSON.stringify(userStore.userInfo) === '{}') {
         // 获取用户信息
         await userStore.getUserInfo()
       }
       // 3.2.判断有没有权限路由
       if (userStore.permissionRouter.length == 0) {
     await userStore.getUserInfo()
     let filterRouter = hasPermission(asyncRouter)
   //**************************************此处添加向数组404******************************************************  
     filterRouter.push(cachAlll)
     // 添加动态路由
     filterRouter.forEach((item) => {
       router.addRoute(item)
     })
     // 打印动态路由以进行调试
     console.log('动态路由:', filterRouter)
     console.log(router.getRoutes())
     userStore.permissionRouter = [...routes, ...filterRouter]
       }
       return true
     }
   })

2.白屏现象

如果按照上面那种方法,可以解决刷新页面出现404的问题,但是会出现白屏的现象

但是为什么会出现404,404的出现是因为没有匹配到任务栏的地址,可是我们已经动态的添加了路由,所以为什么检测不到页面呢????

我参考的别人的博客https://blog.csdn.net/qq_37150410/article/details/128012829?fromshare=blogdetail&sharetype=blogdetail&sharerId=128012829&sharerefer=PC&sharesource=weixin_65363325&sharefrom=from_link,采用了他的方法

具体原因就是:路由守卫里进行的动态路由初始化行不通,因为在进路由守卫之前,程序已经进行了路由匹配,结果就是没匹配到任何内容,自然就报错了。
在这里插入图片描述

这是我的打印

可以发现问题出现在use(router)这里

因为我们连路由前置守卫都没进去,就已经匹配路由了,动态路由还没添加,就肯定报错了

解决方法:https://blog.csdn.net/qq_37150410/article/details/128012829?fromshare=blogdetail&sharetype=blogdetail&sharerId=128012829&sharerefer=PC&sharesource=weixin_65363325&sharefrom=from_link

也是参考上面这位博主 的文章的方法,但是跟她的处理略有不同

上代码

在路由js文件,我把动态追加路由提取出来了

export async function initRouter(){
 const userStore= useUserStore()
  await userStore.getUserInfo()
  let filterRouter = hasPermission(asyncRouter)
  filterRouter.push(cachAlll)
  // 添加动态路由
  filterRouter.forEach((item) => {
    router.addRoute(item)
  })
  // 打印动态路由以进行调试
  console.log('动态路由:', filterRouter)
  console.log(router.getRoutes())
  userStore.permissionRouter = [...routes, ...filterRouter]
}



router.beforeEach(async (to, from) => {
  console.log('路由前置守卫')

  const userStore = useUserStore()
  const token = userStore.token
  // 1.在白名单
  if (whiteList.includes(to.path)) {
    return true
  }
  // 2.不在白名单
  if (!whiteList.includes(to.path) && !token) {
    console.log('不在白名单')
    return '/login'
  }
  // 3.有token
  if (token) {
    // 3.1.判断有没有用户信息
    if (JSON.stringify(userStore.userInfo) === '{}') {
      // 获取用户信息
      await userStore.getUserInfo()
    }
    // 3.2.判断有没有权限路由
    if (userStore.permissionRouter.length == 0) {
      await initRouter()
    }
    return true
  }
})

接下来是最重要的一步

main.js文件在注册router之前,强制初始化一下

async function initMainRouter() {
  await initRouter()
  app.use(ElementPlus, {
    locale: zhCn
  })
  for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
  }

  app.use(createPinia())
  app.use(router)

  console.log('入口文件2')

  app.mount('#app')
}
initMainRouter()

使用await,强行让挂载等待路由初始化完成,彻底将刷新就空白页的问题解决。------引用上面博主文章的话,这个博主的口才真好
转载请注明出处或者链接地址:https://www.qianduange.cn//article/21106.html
标签
评论
发布的文章

C/C | 每日一练 (2)

2025-02-24 13:02:49

Linux性能监控工具汇总

2025-02-24 13:02:48

Python常见面试题的详解16

2025-02-24 13:02:48

QQ登录测试用例报告

2025-02-24 13:02:47

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!