Problems with dynamically adding routes in vue3 [Vue Router warn]: No match found for location with path “xxx“

Problems with dynamically adding routes in vue3

introduction

Recently I want to try vue3 + elementplus + axios + pinia to encapsulate a general backend template. When adding dynamic routing to vue-router, there is an error that does not affect the code running but has a prompt, so I record it to facilitate everyone to solve it.

Console prompt

Insert image description here
The routes circled in the picture are dynamically loaded routes.

solution

Error pages such as 404 no longer need to be placed after all routes. The page routes for error reports can be defined at the beginning.

The reason why the page reports an error that the route cannot be found at the beginning is because to.matched of the dynamically loaded route is an empty array during beforeEach, that is, a blank page will appear when next jumps, and the route will be dynamically added when using addRoute(). has been loaded. At this time, next({ ...to, replace: true }) will jump successfully, so you need to define the 404 page at the beginning to prevent the routing from reporting the error of the above picture.

export const Layout = () => import("@/layout/index.vue");
export const constantRoutes = [
  {
    
    
    path: "/",
    redirect: "/dashboard",
    hidden: true,
  },
  {
    
    
    path: "/login",
    name: "Login",
    component: () => import("@/views/login/index.vue"),
    hidden: true,
  },
  // 404页面
  {
    
    
    path: "/:pathMatch(.*)*",
    component: () => import("@/views/error/index.vue"),
    hidden: true,
  },
  {
    
    
    path: "/dashboard",
    component: Layout,
    redirect: "/dashboard/index",
    hidden: true,
    children: [
      {
    
    
        path: "index",
        name: "Dashboard",
        component: () => import("@/views/dashboard/index.vue"),
      },
    ],
  },
];

export default router;
import router, {
    
     resetRouter } from './router';
import {
    
     getToken } from '@/utils/sessionStorage';
import {
    
     usePermissionStore } from '@/store/permission';

// 判断是否初次或者刷新页面 0表示初次
let isRequest = 0;

router.beforeEach(async (to, _from, next) => {
    
    
  async function init () {
    
    
    // 调用方法获取路由
    const accessRoutes: any = await usePermissionStore().getGenerateRoutes();
    accessRoutes.forEach((route: any) => {
    
    
      router.addRoute(route);
    });
    isRequest = 1;
  }

  // 判断条件根据项目更改
  if (getToken()) {
    
    
    if (to.path === '/login') {
    
    
      next({
    
     path: '/' });
    }
    if (isRequest) {
    
    
      next();
    } else {
    
    
      await init();
      next({
    
     ...to, replace: true });
    }
  } else {
    
    
    sessionStorage.clear();
    isRequest = 0;
    if (to.path === '/login') {
    
    
      next();
    } else {
    
    
      resetRouter();
      next({
    
     path: '/login' });
    }
  }
});

Notice

In vue2, path: " * " is usually used to capture all routes. Vue2's writing method is not supported in vue3, so you need to use regular rules to capture it.

1. /:pathMatch(.*)*  
2. /:pathMatch(.*)

上面两个的区别在于 如果省略最后一个'*'在解析或推送时将对params中的'/'字符进行编码

expand

export const Layout = () => import("@/layout/index.vue");

// vue3 中,当有使用到动态加载路由的情况,使用这种方式引入会出现点击每个大导航栏,Layout 重新加载的情况,因此需要改成上面的写法
import Layout from "@/layout/index.vue";

Insert image description here
After clicking any route in user management, then click any route in personal information. If you use the second method above, the Layout page component will be reloaded! ! !

Guess you like

Origin blog.csdn.net/m0_64344940/article/details/130710796