当前位置: 首页 > news >正文

vue3动态路由

要想实现vite+vue-router实现动态路由我们需要用到

1. addRoute()

官方文档中addRoute的使用

当我们添加一个主路由的时候

router.addRoute({ path: '/permission', name: 'permission', component: () => import('xxxxx')})

添加子路由也就是嵌套路由

router.addRoute('主路由的name', { path: 'settings', component: AdminSettings })

2. 导航守卫使用时的注意事项,否则会出现刷新白屏,或者路由访问死循环等

之前我们使用导航守卫的时候需要一个参数next()去控制是否放行以及去哪个页面,但是在新版本的vue-router里面可以不是用next()

我们可以新建一个permission.ts文件

import router from "./index";
import { useSessionStorage } from "@vueuse/core";
import { StorageEnum } from "@/enum";
import { useUserStore } from "@/store";

const whiteList = ["/login", "/404"];

router.beforeEach(async (to) => {
  const token = useSessionStorage(StorageEnum.TOKEN, "").value;
  // 如果在白名单里面 并且 token 不存在
  if (whiteList.includes(to.path) && !token) {
    return true;
  } else {
    const { menuList, getMenuList } = useUserStore();
    // 如果为空数组,name就请求接口重新获取后端维护的路由数据
    if (!menuList.length) {
      await getMenuList();

      console.log("获取全部路由 =>", router.getRoutes());
      // 触发重定向 不这样写会导致刷新找不到路由 两种写法都行
      // return { path: to.fullPath };
      return to.fullPath;
    }
  }
});

出现404的话比如说你在路由表中维护了下面路由映射

{
 path: "/:pathMatch(.*)",
  name: "page404",
  component: () => import("@/views/system/404.vue"),
}

3. 获取后端tree数据,递归循环,可能业务会有type类型,比如分为模块,菜单,页面,按钮等,到时候结合业务去实现逻辑

4.import.meta.glob()

import.meta.glob动态的去拼接获取文件,把后台返回内容转换成() => import('xxxx')格式

以下代码仅供参考,有很多需要完善的地方

import type { RouterType } from "@/router/type";
import router from "@/router";
import type { RouteRecordRaw } from "vue-router";

export const useRouterConfig = () => {
	// 获取views目录下的所有的文件 不要使用@别名 
  const modules = import.meta.glob("../views/**");
  const asyncRoutes = ref<RouterType[]>([]);

  const addRoutes = (menus: RouterType[]) => {
    asyncRoutes.value = menus;
    filterAsyncRouter();
    // 动态添加 / 路由
    router.addRoute({
      path: "/",
      redirect: asyncRoutes.value[0].path,
    });
  };

  const filterAsyncRouter = () => {
    const routerLoop = (routes: RouterType[], ParentName?: string) => {
      routes.forEach((item) => {
        if (item.component === "Layout") {
          item.component = () => import("@/layout/index.vue");
        } else {
          item.component = resolveComponent(item.component);
        }
        const { title, show, icon, name, path, component, children } = item;
        const route: RouteRecordRaw = {
          component,
          path,
          name,
          meta: {
            title,
            show,
            icon,
          },
          children: children as any,
        };
		
		// 动态添加路由
        if (ParentName) {
          router.addRoute(ParentName, route);
        } else {
          router.addRoute(route);
        }

        if (item.children && item.children.length > 0) {
          routerLoop(item.children, item.name);
        }
      });
    };

    routerLoop(asyncRoutes.value);
  };

  const resolveComponent = (path: string) => {
    console.log(modules);
    // 拿到views下面的所有文件之后,动态拼接`key`去获取value
    const importPage = modules[`../views${path}`];
    if (!importPage) {
      throw new Error(
        `Unknown page ${path}. Is it located under Pages with a .vue extension?`
      );
    }
    return importPage;
  };

  return { addRoutes };
};

相关文章:

  • Cyber Weekly #51
  • C++ 回调函数应用实战:深入理解与高效使用回调函数
  • 网络互连与互联网
  • redis哨兵机制 和集群有什么区别:
  • 用哪个机器学习模型 依靠极少量即时静态数据来训练ai预测足球赛的结果?
  • LeetCode算法题(Go语言实现)_44
  • Linux基本指令2
  • Day 11
  • linux网络设置
  • 协程的原生挂起与恢复机制
  • 【深度学习与大模型基础】第10章-期望、方差和协方差
  • 文献分享: DESSERT基于LSH的多向量检索(Part3.2.外部聚合的联合界)
  • lx2160 LSDK21.08 firmware 笔记 - 0.基于fip.bin 编译流程展开的 makefile 分析
  • DrissionPage详细教程
  • Django3 - 建站基础
  • AcWing 5969. 最大元素和
  • openapi + knife4j的使用
  • C++动态规划基础入门
  • Numpy和OpenCV库匹配查询,安装OpenCV ABI错误
  • 深度学习ResNet模型提取影响特征
  • 报社网站开发做什么/网络推广推广
  • 重庆公司网站seo/全网整合营销
  • bootstrop新闻网站开发/长春seo
  • 企业公司网站建设方案/山东进一步优化
  • 昆山建设局图审中心网站/百度指数查询官网
  • 怎样做网站seo优化/seo快速排名源码