素材巴巴 > 程序开发 >

vue3项目中实现动态路由

程序开发 2023-09-20 09:14:40

完成效果

 
 
  1. 1.登录----根据用户登录获取当前用户的菜单
  2. 2.开始发送ajax 获取菜单
  3. 3.菜单解析为路由相关配置
  4. 4.添加到路由配置当中
  5. 5.动态路由实现完成

第一步:配置静态路由

 
 
//main.ts
 import { createApp } from "vue";
 import "./style.css";
 import App from "./App.vue";
 import "element-plus/theme-chalk/index.css";
 //导入
 import router from "./router/index";
 //将路由关联到vue3 项目
 createApp(App).use(router).mount("#app");
 
 
路由模块文件
 index.ts
 import { createRouter, createWebHistory } from "vue-router";import routes from "./routes";const router = createRouter({
 history: createWebHistory(),
 routes,
 scrollBehavior(to, from, savePosiation) {
 if (savePosiation) {
 return savePosiation;
 }
 return { left: 0, top: 0 };
 },
 });export default router;//静态路由配置文件
 //路由配置
 //引入组件
 import Index from "@/views/Index.vue";
 import Login from "@/views/Login.vue";
 import NotFound from "@/views/Not-found.vue";export default [
 {
 path: "/",
 component: Index,
 name: "admin",
 },
 {
 path: "/login",
 component: Login,
 },
 {
 path: "/not-found",
 component: NotFound,
 },
 {
 path: "/:pathMatch(.*)*", //vue2 * vue3 改为正则
 redirect: "/not-found",
 },
 ];

第二步实现登录和安全守卫

 
 
//守卫
 let whiteList = ["/login", "/not-found"];
 router.beforeEach((to, from) => {
 //读取token
 let token = localStorage.getItem("_token");//未登录
 if (!token) {
 if (whiteList.indexOf(to.path) == -1) {
 return { path: "/login" };
 }
 } else {
 if (to.path == "/login") {
 return { path: "/" };
 }
 }
 });

第三步:发送请求获取用户动态菜单

 
 
1.获取用户菜单接口
 //用户模块import { get } from "../utils/request";//获取用户菜单
 export const getUserMenu = () => {
 return get("/getRouters");
 };
 
 
2.在守卫中发送请求获取menu
 //守卫
 let whiteList = ["/login", "/not-found"];
 //定义菜单
 let Menu: any = null;
 router.beforeEach(async (to, from) => {
 //读取token
 let token = localStorage.getItem("_token");//未登录
 if (!token) {
 if (whiteList.indexOf(to.path) == -1) {
 return { path: "/login" };
 }
 } else {
 if (to.path == "/login") {
 return { path: "/" };
 }
 //能检测到登录完成
 if (!Menu) {
 //发送请求
 let res = await getUserMenu();
 console.log(res.data.data);
 }
 }
 });

 
 
3.封装一个递归方法解析菜单
 //解析菜单
 function CompilerMenu(arr: Array) {
 if (!arr.length) {
 return;
 }
 arr.forEach((item) => {
 //定义对象
 let rts = {
 name: item.name,
 path: item.path,
 meta: item.meta,
 component: item.component,
 };
 //如果存在子集进行递归解析
 if (item.children && item.children.length) {
 CompilerMenu(item.children);
 }
 console.log(rts);
 });

 
 
4.针对解析的数据 进行组件懒加载
 vite工具
 import.meta.glob()
 //使用vite懒加载
 let Module = import.meta.glob("@/views/**/*.vue");
 console.log("====================================");
 console.log(Module);
 console.log("====================================");

 
 
5.将item.component 解析为组件动态
 //如果没有子集 证明为路由层
 if (!item.children) {
 //实现组件懒加载
 let paths = loadComponent(item.component);
 console.log(paths);
 }//懒加载组件
 function loadComponent(url: string) {
 let path = Module[`/src/views/$.vue`];
 return path;
 }
 
 
6.调用addRouter实现动态路由添加
 //如果没有子集 证明为路由层
 if (!item.children) {
 //实现组件懒加载
 let paths = loadComponent(item.component);
 rts.component = paths;
 console.log(rts);
 //添加动态路由
 router.addRoute("admin", rts);
 }
 });
 
 
  1. 7.检测动态路由添加
  2. //检测动态路由
  3. console.log(router.getRoutes(), router.hasRoute("Housepay"));

第四步测试动态路由

配置二级动态

 
 

 

刷新导致动态路由匹配不到 直接 404

 
 
刷新 使用动态路径匹配的时候在路由中没有对应的路由 直接匹配到*路由 重定向到404
 守卫添加以下代码
 //手动添加404相关处理
 router.addRoute({
 path: "/not-found",
 component: NotFound,
 });
 router.addRoute({
 path: "/:pathMatch(.*)*", //vue2 * vue3 改为正则
 redirect: "/not-found",
 });
 console.log(router.getRoutes());
 //处理
 return { path: to.path };
 静态配置中404 *路由删除 采用手动配置。

第五步设置菜单数据缓存

 
 
//设置菜单数据缓存
 localStorage.setItem("_menu", JSON.stringify(Menu));组件中进行递归
 
 

最后实现最终效果


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。