在使用vue3 的小伙伴,在使用vue3 时候必须使用vue-router4,我最近在使用这个时候异常恼火,因为报错 [Vue Router warn]: No match found for location with path "xxx"  解决了好几天,才玩明白,话不多说我们一步一步来

Vue Router | Vue.js 的官方路由

声明:这里没去写路由基础使用,核心是动态路由使用。

一、 下载安装

yarn add vue-router / npm i vue-router 

二、 引入使用,引出问题

基本使用

我这里只提供核心部分,其他基础页面,你可以自己手动建立,无要求

main.ts

import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
import router from "./router/router";

const app = createApp(App);
app.use(router);

app.mount("#app");

注释:config 是我自己的路由处理数据,最终处理成路由的数据,结果就是普通的路由数据, 如果有人需要话,我给他发,或者到时候加到文章中

优化前的  router/index.ts

import {
  NavigationGuardNext,
  RouteLocationNormalized,
  RouteRecordRaw,
  createRouter,
  createWebHistory,
} from "vue-router";
//  config 是我自己的路由处理数据,最终处理成路由的数据
import config from "@/config/config";
// 静态路由
const staticRoutes: RouteRecordRaw[] = [
  {
    component: () => import("@/pages/login/login.vue"),
    name: "login",
    path: "/login",
  },
  {
    path: "/",
    redirect: "/login",
  },
  {
    path: "/:pathMatch(.*)*", 
    component: () => import("@/pages/NotFount.vue"),
  },
];
const router = createRouter({
  history: createWebHistory(),
  routes: [...staticRoutes],
});
// 是否首次获取进来, 你也可以定义全局状态,根据动态路由数据
let status = true;
router.beforeEach(
  (
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: NavigationGuardNext
  ) => {
    if (status) {
      /**
       *  config 是我自己的路由处理数据,最终处理成路由的数据
       *  处理过程我就不放出来了,毕竟我相信大家都会处理
       */
      config?.routes.forEach((v) => router.addRoute(v));
      status = false;
      next({ ...to, replace: true });

      return;
    }
    next();
  }
);
export default router;

在这里我们必须将路由分为两部分, 一部分是静态路由(不涉及到权限功能的页面)、另一部则是动态路由。  全部处理成动态我是没弄出来, 如果有能力的小伙伴弄出来,麻烦给我分享一下方法  谢谢。

/:pathMatch(.) 是什么?

“/:pathMatch(.)” 是一个路径匹配的通配符,常用于路由定义或路由表中。它表示匹配任何路径片段,其中 :pathMatch 是一个占位符,后面的 (.*) 表示匹配任意字符。所以 “/:pathMatch(.*)” 可以匹配任何路径。这个通配符的作用是在路由中捕获动态路径参数,使得路由能够处理各种不同的路径。例如,可以利用这个通配符来实现一些基于路径的动态页面加载或参数的传递。

next 有两种情况

当然可能有一些人不懂 next({ ...to, replace: true }) 作用我这边再给解释一下

第一种不传递参数 next()   不传递, 就直接通过,进入了对应界面,

第二种传递参数 next({ ...to, replace: true })  有参数了,就执行为 中断当前进程,根据给next传递的参数,重新执行 (这里重新执行beforeEach)

为什么使用next({ ...to, replace: true }) 

因为我们是在beforeEach中添加的动态路由,在加载这个配置之前,我们就调用路由路径,这样你就会访问不到这个界面(究其原因是追加到路由配置中的不是同步生效的),就会导致404 或者空白界面(这个要看你的配置项)

配置完成

此时我们使用路由,跳转访问都没有任何问题。

问题开始暴露

这时候细心的小伙伴就会发现,在动态路由界面刷新时候就会抛出这个异常,当然他不会影响你的功能。但是你看到后又很别扭(我在这卡了好几天)

这里你配置了静态路由包含404界面,就会进入到404界面不出抛出这个异常 如果没有配置404界面,那么你就看到如下报错

这个问题解决思路就是, 再首次进来时候判断当前的是否要去404页面并且to.redirectedFrom(

包含在重定向到当前地址之前,我们最初想访问的地址 , 并且redirectedFrom不能为空时,重定向到之前个那地址去,为undefined时,当前访问正常(此时访问的应该是静态路由)) 

这个时候我们就能够完美使用这个了

优化后的  router/index.ts

import {
  NavigationGuardNext,
  RouteLocationNormalized,
  RouteRecordRaw,
  createRouter,
  createWebHistory,
} from "vue-router";
import config from "@/config/config";
// 静态路由
const staticRoutes: RouteRecordRaw[] = [
  {
    component: () => import("@/pages/login/login.vue"),
    name: "login",
    path: "/login",
  },
  {
    path: "/",
    redirect: "/login",
  },
  {
    path: "/:pathMatch(.*)*",
    component: () => import("@/pages/NotFount.vue"),
  },
];
const router = createRouter({
  history: createWebHistory(),
  routes: [...staticRoutes],
});
// 是否首次获取进来
let status = true;
router.beforeEach(
  (
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: NavigationGuardNext
  ) => {
    console.log("to",to);
    
    if (status) {
      /**
       *  config 是我自己的路由处理数据,最终处理成路由的数据
       *  处理过程我就不放出来了,毕竟我相信大家都会处理
       */
      config?.routes.forEach((v) => router.addRoute(v));
      status = false;
      //  如果to.redirectedFrom 不成立就说明,精准匹配了当前界面,如果是/:pathMatch(.*)* 匹配到就会有值
      if (to.redirectedFrom != undefined) {
        next({ path: to.redirectedFrom?.fullPath, replace: true });
      } else {
        next({ ...to, replace: true });
      }
      return;
    }
    next();
  }
);
export default router;

我之前翻阅了一些文章,我看他们是使用这种方式去匹配的,这种也可以,其实就是路径正则匹配

 {
    path: "/:W+",
    component: () => import("@/pages/NotFount.vue"),
  },

全部思路就是如此了,就是一个简单的操作。

好了,到此结束,后续如有问题,再做修改

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐