在vue项目中,大家做权限管理的时候,大部分是采用addRoute方案来实现。

在之前使用vue-router的时候,大家在动态追加完路由后,还要再追加一下404页面,如果在路由文件中直接写好404页面,那么刷新页面的时候就会跳转到404页面,原因在于,我们在加动态路由前,就配置了通配符404路由.改成动态添加过路由后,再最后push一下404通配符,这样就可以了。

路由全局守卫:

router.beforeEach(async (to, from, next) => {
    ...// 其他逻辑省略,只看addRoutes部分
    try {
        await store.dispatch('GetUserInfo')
        const res = await store.dispatch('getAsyncRoutes')
        const asyncRoutes = handleRoutes(res)
        router.addRoutes(asyncRoutes);
        router.addRoutes({
            path: "*", 
            name: "404", 
            component: () => import("@/views/error/404") 
        })
        next({ ...to, replace: true })
    } catch (error) {
        next(`/login?redirect=${to.path}`)
    }
})

后来vue-router升级,如果还像上面那样动态追加404的话,会有问题:刷新页面,如果当前是动态追加的路由,控制台会报警告:

[Vue Router warn]: No match found for location with path “xxxxx”

这是因为,我们刷新页面或者第一次访问动态的路由,全局守卫beforeEach执行,但是这时候我们还没有动态追加路由,找不到,而且我们是后续追加的404,从而导致第一次路由的matched为空,所以就报了这个警告,请看刷新页面后,控制台打印的结果:

在这里插入图片描述

解决办法:

升级后的vue-router已经不需要再动态追加404路由了,直接写到初始化的router文件里就好:

router/index.ts:

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes: Array<RouteRecordRaw> = [
    ...// 其他路由省略
    {
        path: '/:catchAll(.*)',
        name: '404',
        component: () => import('@/views/error/index.vue')
    }
]
const router = createRouter({
    history: createWebHistory(),
    routes
})
export default router

全局守卫:

router.beforeEach(async (to) => {
    ...// 其他逻辑省略
    try {
        await userStore.getUserInfo()
        const res: any = await appStore.getAsyncRoutes()
        const asyncRoutes = handleRoutes(res)
        asyncRoutes.forEach((item) => router.addRoute('layout', item))
        return to.fullPath
    } catch (error) {
        return `/login?redirect=${to.fullPath}`
    }
})

这样,当刷新页面,第一次走beforeEach的时候,因为还没动态追加路由,会匹配到404,这样matched就不是空的,就不会报警告了:

在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐