2023-08-10 09:23阅读: 401评论: 0推荐: 0

vite+vue3+ts+elementPlus前端框架搭建 [三] router路由管理

路由包括动态路由、静态路由两种,本文中以静态路由的方式实现了动态路由。

1. 创建Router

在Src目录下创建router文件夹,并在router文件夹下创建index.ts文件。

index.ts文件内容如下:
import { reactive } from "vue";
import * as VueRouter from "vue-router";
import { useUserStore } from "@/store/modules/user";
import { ElNotification } from "element-plus";
import dynamicRouter from "./dynamic";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
NProgress.configure({ showSpinner: false });


//系统特殊路由

const routes_404 = {

path: "/:pathMatch(.)",

hidden: true,

component: () => import("@/layout/other/404.vue"),

};

let routes_404_r = () => {};

const routes = [

{

name: "layout",

path: "/",

redirect: "/dashboard",

component: () => import("@/layout/index.vue"),

children: [],

},

{

path: "/login",

component: () => import("../views/login/index.vue"),

},

];

const router = VueRouter.createRouter({

history: VueRouter.createWebHistory(),

routes,

// 刷新时,滚动条位置还原

scrollBehavior: () => ({ left: 0, top: 0 }),

});

var isLoadRouter = false;

router.beforeEach(async (to, _from, next) => {

const userStore = useUserStore();

NProgress.start();

if (to.path === "/login" && !userStore.user) {

//删除路由(替换当前layout路由)

router.addRoute(routes[0]);

//删除路由(404)

routes_404_r();

isLoadRouter = false;

next();

return false;

}

if (to.path === "/login" && userStore.user) {

next("/");

return false;

}

if (!userStore.user) {

next("/login");

return false;

}

//整页路由处理

if (to.meta.fullpage) {

to.matched = [to.matched[to.matched.length - 1]];

}

//加载动态路由  dynamicRouter 如果通过程序加载,可以通过localStorage在登录页面存入路由数据,并在这里localStorage取出来

if (!isLoadRouter) {

var menuRouter = filterAsyncRouter(dynamicRouter);

menuRouter = flatAsyncRoutes(menuRouter);

menuRouter.forEach((item) => {

router.addRoute("layout", item);

});

routes_404_r = router.addRoute(routes_404);

if (to.matched.length == 0) {

router.push(to.fullPath);

}

isLoadRouter = true;

}

next();

NProgress.done();

});

router.afterEach(() => {

NProgress.done();

});

router.onError((error) => {

NProgress.done();

ElNotification.error({

title: "路由错误",

message: error.message,

});

});

function filterAsyncRouter(routerMap) {

const accessedRouters: any[] = [];

routerMap.forEach((item) => {

item.meta = item.meta ? item.meta : {};

//处理外部链接特殊路由

if (item.meta.type == "iframe") {

item.meta.url = item.path;

item.path = /i/${item.name};

}

//MAP转路由对象

var route = {

path: item.path,

name: item.name,

meta: item.meta,

redirect: item.redirect,

children: item.children ? filterAsyncRouter(item.children) : null,

component: resolveComponent(item.component),

};

accessedRouters.push(route);

});

return accessedRouters;

}

// 加载.vue文件

const pages = import.meta.glob("@/views/**/*.vue");

const resolveComponent = (name: any) => {

const importPage = pages[/src/views/${name}.vue];

if (!importPage) {

return () => import(@/layout/other/empty.vue);

}

return importPage;

};

function flatAsyncRoutes(routes, breadcrumb = []) {

let res = reactive([]);

routes.forEach((route) => {

const tmp = { ...route };

if (tmp.children) {

let childrenBreadcrumb = [...breadcrumb];

childrenBreadcrumb.push(route);

let tmpRoute = { ...route };

tmpRoute.meta.breadcrumb = childrenBreadcrumb;

delete tmpRoute.children;

res.push(tmpRoute);

let childrenRoutes = flatAsyncRoutes(tmp.children, childrenBreadcrumb);

childrenRoutes.map((item) => {

res.push(item);

});

} else {

let tmpBreadcrumb = [...breadcrumb];

tmpBreadcrumb.push(tmp);

tmp.meta.breadcrumb = tmpBreadcrumb;

res.push(tmp);

}

});

return res;

}

//过滤树

function treeFilter(tree, func) {

return tree

.map((node) => ({ ...node }))

.filter((node) => {

node.children = node.children && treeFilter(node.children, func);

return func(node) || (node.children && node.children.length);

});

}


/i/${item.name}
/src/views/${name}.vue
@/layout/other/empty.vue
export default router;

2. 动态路由dynamic.ts

在动态路由dynamic.ts文件增加模拟动态路由内容。

dynamic.ts内容如下:
const routes = [
  {
    name: "home",
    path: "/home",
    meta: {
      title: "首页",
      icon: "ElemeFilled",
      type: "menu",
    },
    children: [
      {
        name: "dashboard",
        path: "/dashboard",
        meta: {
          title: "控制台",
          icon: "Menu",
          affix: true,
        },
        component: "home/index",
      },
      {
        name: "directive",
        path: "/other/directive",
        meta: {
          title: "指令",
          icon: "Flag",
        },
        component: "other/directive",
      },
      {
        path: "https://baidu.com",
        name: "外链百度",
        meta: {
          title: "外链百度",
          icon: "Link",
          type: "link",
        },
      },
      {
        path: "/other/fullpage",
        name: "fullpage",
        meta: {
          title: "整页路由",
          icon: "Monitor",
          fullpage: true,
          hidden: true,
          type: "menu",
        },
        component: "other/fullpage",
      },
    ],
  },
  {
    path: "/other/about",
    name: "about",
    meta: {
      title: "关于",
      icon: "InfoFilled",
      type: "menu",
    },
    component: "other/about",
  },
];
export default routes;

3. 在main.ts文件注册router

import router from "./router";
app.use(ElementPlus).use(store).use(router).mount("#app");

本文作者:Jason.裕哥

本文链接:https://www.cnblogs.com/fuyu-blog/p/17619461.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Jason.裕哥  阅读(401)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起