【vue-router 4.x】使用addRoute加载动态路由时,刷新页面后出现空白页和控制台报错 [Vue Router warn]: No match found for location with path "/***/index"

"vue-router": "^4.1.6" 遇到的问题

  1. 动态路由刷新后,出现空白页
  2. 动态路由刷新后,控制报错[Vue Router warn]: No match found for location with path "/***/index"

1.动态路由,刷新后出现空白页如何解决

通过打断点可知,刷新后进入页面,to.matched为空数组,即此时next跳转则会出现空白页面。
使用next({ ...to, replace: true })来确保addRoute()时动态添加的路由已经被完全加载上去。

next({ ...to}) 能保证找不到路由的时候重新执行beforeEach钩子

next({ replace: true}) 保证刷新时不允许用户后退

路由拦截器

router.beforeEach(async (to, from, next) => {
    // 1.NProgress 开始
    NProgress.start()

    // 2.路由跳转之前,清除所有的请求
    axiosCanceler.removeAllPending()

    // 3.判断是访问登录页,直接方向
    if (to.path === LOGIN_URL) return next()

    // 4.判断是否有token,没有重定向到登录页面
    const globalStore = GlobalStore()
    if (!globalStore.token) return next({ path: LOGIN_URL, replace: true })

    // 5.如果没有菜单列表,就重新请求菜单列表并添加动态路由( next({ ...to, }) 会不停调用beforeEach直到找到to.matched)
    const authStore = AuthStore()
    if (!authStore.authMenuListGet.length) {
        await initDynamicRouter()
        return next({ ...to, replace: true })
    }
    // 6.放行页面
    next()
})

添加动态路由的方法(仅参考)

export const initDynamicRouter = async () => {
    try {
        // 1.获取菜单列表 && 按钮权限
        const authStore = AuthStore()
        await authStore.getAuthButtonList()
        await authStore.getAuthMenuList()

        // 2.判断当前用户有没有菜单权限
        if (!authStore.authMenuListGet.length) {
            ElNotification({
                title: "无权访问",
                message: "当前账号无任何菜单权限,请联系系统管理员!",
                type: "warning",
                duration: 3000
            })
            router.replace(LOGIN_URL)
            return Promise.reject("No permission")
        }

        // 3.添加动态路由(通过getFlatArr 方法把菜单全部处理成一维数组,方便添加动态路由
        let dynamicRouter = getFlatArr(JSON.parse(JSON.stringify(authStore.authMenuList)))
        dynamicRouter.forEach((item: any) => {
            if (item.children) delete item.children
            if (item.component) item.component = modules["/src/views" + item.component + ".vue"]
			// 判断是否为全屏路由
			if (item.meta.isFull) {
				router.addRoute(item);
			} else {
				// 添加到父路由layout下面添加新的路由
				router.addRoute("layout", item);
			}
        })

    } catch (error) {
        // 当按钮和菜单 请求出错时,重定向到登录页
        router.replace(LOGIN_URL)
        return Promise.reject(error)
    }
}

2.刷新后控制台报错如何解决

添加一个静态路由,匹配任意路径指向404错误页面。这样能保证控制不会报错[Vue Router warn]: No match found for location with path "/***/index"

export const staticRouter: RouteRecordRaw[] = [
    {
        path: "/",
        redirect: LOGIN_URL
    },
    {
        path: LOGIN_URL,
        name: "login",
        component: () => import("@/views/login/index.vue"),
        meta: {
            title: "登录页"
        }
    },
    // 主页框架
    {
        path: "/layout",
        name: "layout",
        component: () => import("@/layouts/LayoutVertical/index.vue"),
        redirect: HOME_URL,
        children: []
    },
    {
        // hide: true,
        path: '/:pathMatch(.*)*',
        component: () => import('@/components/ErrorMessage/404.vue'),
    }
]
posted @ 2022-12-04 16:09  wanglei1900  阅读(5356)  评论(0编辑  收藏  举报