首页 > 其他分享 >vue3动态路由及菜单

vue3动态路由及菜单

时间:2022-10-02 10:07:27浏览次数:45  
标签:菜单 name import vue3 path router 动态 路由


一般来说,前端项目中的路由,很有可能是需要动态注册的。因为菜单可能在管理系统中维护,还跟权限绑定,用户登录以后,需要动态展示菜单。菜单往往跟路由挂钩,因此,路由需要动态注册。

具体如何实现呢?思路是,系统只提供默认的路由,登录以后,读入菜单/路由数据,加载。这其中,可能会出现默认路由与动态路由有重叠的情况。处理办法是覆盖。数据结构方面,菜单与路由数据二合一。

一、项目结构

这是我们一个项目的公共框架的代码结构。我们打算在src/modules/存放具体业务系统的代码,而外部是相对稳定,可以复用的框架代码。

vue3动态路由及菜单_addRoute

二、默认路由

src/router/default.js,内容比较少,只有登录、首页、404三个。其余全都靠动态注册。

路由项中,自定义属性放在meta里。动态路由与默认路由的数据结构一致。

/**
* 默认路由
* 具体业务路由,应在src/modules/router里定义,或者从后端动态加载
*/
export default [
/**
* 路由项结构:
*{
path: "/",//路径,(必选;path、name、component是路由规定必选的元素)
也可以带参数,如 path: "/resource/detail/:id",
name: "路由名称,是路由唯一标识",(必选)
component: 指向组件,如 Home,或者() => import("../views/login/PageIndex.vue"),(必选)
meta: {//meta里的属性可以自定义,全部为可选项
text: "名称",//展示在菜单里,(可选)
navi: true, //导航条(一级菜单),(可选)
noLogin: true, //无须登录即可浏览,(可选)
access: "work:sysmanage,work:resourcemanage",//权限标识,(可选)
},
children: [],
},
*/
{
path: "/login",
name: "login",
component: () => import("../views/login/PageIndex.vue"),
meta: {
noLogin: true, //无须登录即可浏览
},
},
{
path: "/",
name: "Home",
component: () => import("../views/PageIndex.vue"),
},
{
path: "/notAllow",
name: "notAllow",
component: () => import("../views/sys/notAllow.vue"),
},
];

export const HomeName = "Home";

三、动态注册

注册的时机是什么?在哪里注册?怎么注册?

答曰:登录之后注册;在路由守卫里注册;用router.addRoute()一个个加进去。

1、登录之后进行注册,在路由卫士里注册

所谓路由守卫,就是路由规则。这名字我是从网上抄过来的。

src/router/index.js

import { createRouter, createWebHashHistory } from "vue-router";
import routes from "./default";
import routeAssembler from "./setup";
import { hasAuthority } from "@/utils/login.js";

const router = createRouter({
history: createWebHashHistory(),
routes,
});

// 路由守卫
let registerRouteFresh = true;//是否还没有动态加载过
router.beforeEach((to, from,) => {
const isLogin = localStorage.isLogin ? true : false;
if (isLogin) {
//已登录情况下验证权限
let isAccess = hasAuthority(to.meta.access);
if (!isAccess) {//没有权限
next("/notAllow");
return;
}
if (registerRouteFresh) {//还没有动态加载过
//动态注册路由 <----------------------------------------
routeAssembler(router);
registerRouteFresh = false;
next({ ...to, replace: true });
} else {
//已经登录了,不能再打开登录页
to.path === "/login" ? next("home") : next();
}
} else {
//如果无须登录则直接打开,否则转向登录页面
to.meta.noLogin || to.path === "/login" ? next() : next("/login");
}
});

export default router;

2、如何动态注册
src/router/setup.js,即上面例子中的routeAssembler:

/*
装配路由及菜单
*/
import fixItems from "./default"; //默认路由
import { HomeName } from "./default"; //统一命名首页路由项(参考前面的默认路由)
import projectItems from "@/modules/router"; //具体业务系统的路由

export default (router) => {
//获得动态路由
const dynaItems = getDynamicItems();

//对齐首页(统一命名首页)
adpatHome(HomeName, dynaItems);

//添加动态路由
dynaItems.forEach((value) => {
router.addRoute(value);
});
};

const getDynamicItems = () => {
/*
获取动态路由,从指定文件加载或从后端获取
*/
return projectItems;
};

//默认路由与业务路由对齐首页的路由信息
//所谓对齐,就是大家的name保持一致,这样才能保证动态加入的路由项,覆盖掉前面的path和name相同的路由
const adpatHome = (HomeName,) => {
let home = dynaItems.filter((item) => {
return item.path === "/";
});
if (home.length > 0 && home[0].name !== HomeName) {
/**
* 如果业务路由定义了首页,但其name与默认路由首页的name不相同
* 则将业务路由中首页项的name置为默认名称
* 因为按照vue-router的规则,addRoute的时候,如果存在同名同路径的路由项,则覆盖之
* 我们要的就是覆盖默认,以业务路由设置为准
*/
home[0].name = HomeName;
}
};

这里面有个如果动态路由,与默认路由中存在相同的路由项,该如何处理的问题。

按照vue3的router规则,如果后面加进来的路由项,仅仅是path相同,而name不同,则不算是相同的路由项,addRoute()进去之后,仍然是原先的路由项起作用;但如果是path和name都相同,则原先的会被覆盖(我怀疑是name相同就会被覆盖)。所以,默认路由中有首页路由,指向框架代码中的默认首页;加载动态路由后,该路由被覆盖,指向了具体业务系统的首页。这也表明,我们无须自己手动删除已加载的同名路由项。事实上,删除还会报错。



标签:菜单,name,import,vue3,path,router,动态,路由
From: https://blog.51cto.com/leftfist/5729202

相关文章

  • 一起来配置静态路由吧~
    交换机连接相同网段计算机,路由器连接不同网段的计算机。当使用路由器连接时,在对应端口上配置网关地址,就可以使路由器两侧计算机达到互通的效果。但如果路由器与路由器相连......
  • 路由基础之OSPF中级网络工程师企业网络架构
    路由基础之中级网络工程师企业网络架构​原理概述:​防火墙(英语:Firewall)技术是通过有机结合各类用于安全管理与筛选的软件和硬件设备,帮助计算机网络于其内、外网之间构建一道......
  • Vue路由跳转到新页面之后,返回旧页面保持状态不变
    新项目中遇到了登录时点击用户协议,进入协议页面让用户阅读,然后返回登录页面时发现原来填写的手机号验证码全都没有了。解决方案:使用keep-alive在vue.app中添加keep-alive......
  • vue3 自定义指令控制按钮权限
    经过1个周的摸索和查阅资料,终于搞定VUE3中自定义指令,实现按钮级别的权限控制。当然,只是简单的对按钮进行隐藏和删除的dom操作比较容易,一直纠结的是当按钮无权限时,不是直接......
  • BGP路由技术
    ......
  • 设置mode='out-on'导致路由切换过快路由加载报错 Failed to execute 'insertBefore'
    原代码:  解决代码:  原因未知 ......
  • Arco Pro + Vite + vue3 + ts 动态引入组件
    有个需求是在组件中动态导入组件, 但vite自身对动态字符串形式的组件引入是有限制的, 以下写法会报错   官方文档中也对此有做说明   改为以下形式就不......
  • Vue3 + React18 + TS4 入门到实战
    前端项目开发,基本绕不开Vue+TS或React+TS,因此,这已经成为前端开发工程师日常需掌握的三大热门技术。本课程针对真正的初级前端同学而设,带大家系统地掌握3者目前新版......
  • 国庆节,零代码帮你搞定假期美食菜单
    当国庆假期遇上美食每一口都唇齿留香特色美食太多,不知道吃什么?AppCube带你一分钟搞定假期美食来一场舌尖上的旅行零代码,让假期生活有滋有味国庆小长假,三五好友结伴......
  • 国庆节,零代码帮你搞定假期美食菜单
    当国庆假期遇上美食每一口都唇齿留香特色美食太多,不知道吃什么?AppCube带你一分钟搞定假期美食来一场舌尖上的旅行零代码,让假期生活有滋有味国庆小长假,三五好友结伴出游,最纠......