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

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);

});

}
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");

vite+vue3+ts+elementPlus前端框架搭建 [三] router路由管理的更多相关文章

  1. 全面解析JavaScript的Backbone.js框架中的Router路由

    这篇文章主要介绍了Backbone.js框架中的Router路由功能,Router在Backbone中相当于一个MVC框架中的Controller控制器功能,需要的朋友可以参考下. Backbone ...

  2. 基 vue-element-admin升级的Vue3 +TS +Element-Plus 版本的后端管理前端解决方案 vue3-element-admin 正式对外发布,有来开源组织又一精心力作,毫无保留开放从0到1构建过程

    项目简介 vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 + Element Plus 版本的后台管理前端解决方案,是 有来技术团队 继 youla ...

  3. Unity 游戏框架搭建 (三) MonoBehaviour单例的模板

      上一篇文章讲述了如何设计C#单例的模板.也随之抛出了问题: 如何设计接收MonoBehaviour生命周期的单例的模板? 如何设计? 先分析下需求:   1.约束脚本实例对象的个数.   2.约束 ...

  4. ASP.NET Core微服务+Tabler前端框架搭建个人博客1--开始前想说的话

    写在前面 本人为在读研究生,特别喜欢.NET,觉得.NET的编程方式.语法都特别友好,学习.NET Core已经差不多有一年半了,从一开始不知道如何入门到现在终于可以编写一些小的应用程序,想一想还是非 ...

  5. 手把手教你使用VUE+SpringMVC+Spring+Mybatis+Maven构建属于你自己的电商系统之vue后台前端框架搭建——猿实战01

            猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...

  6. .Net Core3.0 WebApi 项目框架搭建 三:读取appsettings.json

    .Net Core3.0 WebApi 项目框架搭建:目录 appsettings.json 我们在写项目时往往会把一些经常变动的,可能会变动的参数写到配置文件.数据库中等可以存储数据且方便配置的地方 ...

  7. OnsenUI 前端框架(三)

    上一章咱们学习了OnsenUI的工具栏.侧边栏和标签栏.通过对页面上这三部分的学习,咱们对混合应用的一个页面有了大体上的认识.从这一章开始,咱们学习OnsenUI混合项目开发过程中会用到的各种各样的组 ...

  8. 自定义统一api返回json格式(app后台框架搭建三)

    在统一json自定义格式的方式有多种:1,直接重写@reposeBody的实现,2,自定义一个注解,自己去解析对象成为json字符串进行返回 第一种方式,我就不推荐,想弄得的话,可以自己去研究一下源码 ...

  9. ASP.NET Core微服务+Tabler前端框架搭建个人博客2--系统架构

    功能分析 在整个微服务架构的搭建过程中,我们需要做的第一步就是对服务进行拆分,将一个完整的系统模块化,通过对各个模块互联,共同完成一个系统的工作.既然要做到模块化,那么必须明白你的系统的需求到底是什么 ...

  10. VUE3企业级项目基础框架搭建流程(1)

    开发环境和技术栈 操作系统 windows11 开发工具 vscode.phpstudy(小皮):nginx1.15.11, mysql5.7.26, php7.4,Navicat for MySQL ...

随机推荐

  1. 云效DevOps实践-如何基于云效实现测试自动化集成和分析

    简介: 对于现代软件研发来说,持续.快速.高质量.低风险地交付需求特性,是业务对研发的主要诉求.而要做到这一点,除了要有良好的架构设计.卓越的工程能力,快速可靠的测试反馈也是其非常重要的一环,达到这一 ...

  2. DDD as Code:如何用代码诠释领域驱动设计?

    简介: 相较于常规的MVC架构,DDD更抽象.更难以理解,各个开发者对DDD的解释也不尽相同.那么哪种设计方式才更好?在学习时如何知道哪种DDD更正统,没有被别人带歪?本文尝试使用"DDD ...

  3. Serverless Kubernetes 落地实践

    ​简介:如何通过原生 Kubernetes 提供 Serverless 能力?如何借力丰富的云原生社区生态?本文将给大家介绍一下我们在 Serverless Kubernetes 上的落地实践. 作者 ...

  4. CSS3 transition动画、transform变换、animation动画

    一.CSS3 transition动画 transition可以实现动态效果,实际上是一定时间之内,一组css属性变换到另一组属性的动画展示过程. 属性参数: 1.transition-propert ...

  5. [FAQ] uni-app 如何让页面不展示返回箭头图标

    默认情况是,有历史上一页的 页面会在左上角展示返回图标. 比如登录页不想展示返回,在跳转进来时可以使用 uni.redirectTo({}),它能够关闭其它页面,这样当前页就不会有返回箭头了. Ref ...

  6. WPF 获取本机所有字体拿到每个字符的宽度和高度

    本文主要采用 GlyphTypeface 类尝试获取每个字符的宽度和高度的值,尽管这个方法和最终 WPF 布局使用的文本的宽度和高度是不相同的,但是依然可以作为参考 获取系统字体文件夹的文件 系统字体 ...

  7. Postergresql常见操作

    Postergresql常见操作 1. 安装部署 略 2. 登录数据库 查看版本 ## 以管理员身份 postgres 登陆,然后通过#psql -U postgres#sudo -i -u post ...

  8. ansible系列(31)--ansible实战之部署WEB集群架构(1)

    目录 1. WEB集群环境说明 2. ansible部署WEB集群实现思路 3. ansible基础环境部署 1. WEB集群环境说明 WEB集群环境说明如下: 客户端:模拟外网主机,地址:192.1 ...

  9. 网络安全—模拟IP代理隐藏身份

    文章目录 网络拓扑 安装 使用 代理服务器设置 隐藏者设置 使用古老的ccproxy实现代理服务器,仅做实验用途,禁止做违法犯罪的事情,后果自负. 网络拓扑 均使用Windows Server 200 ...

  10. 节能降耗 | AIRIOT智慧电力综合管理解决方案

      电力技术的发展推动各行各业的生产力,与此同时,企业中高能耗设备的应用以及输配电过程中的电能损耗,也在一定程度上加剧了电能供应压力.以工业制造业为例,企业的管理水平.能耗结构.生产组织方式都关系到能 ...