vue菜单权限设计实现,vue权限管理菜单思路
本文主要介绍vue实现菜单权限控制的示例代码。文中详细介绍了示例代码,对大家的学习或工作有一定的参考价值。有需要的朋友下面和边肖一起学习。
你做后台管理系统的时候,一般会涉及到菜单的权限控制。当然,解决问题的方法只有两种:——前端控制和后端控制。我们公司产品迭代比较快,所以从前端控制路线迭代到后端控制路线。我将介绍这两种方法的优缺点以及如何实现(不熟悉vue-router API的可以先去官网看一波API)。
先简单说一下项目的需求:如下图,有一级菜单和二级菜单,然后不同的人登录显示不同的菜单。
前端路由控制的思路:把所有的路由映射表拿到前端维护,也就是所有的菜单路径和对应的组件都写在我的router.js后面我会提到全部写进去的弊端。然后我的左边菜单被写成一个组件(sidebar.vue),在里面我写了一段这样的数据,然后通过登录时获得的等级值在数据中的固定菜单中添加hidden,然后前端根据hidden显示菜单。
//router.js伪代码
const log in=r=require . assure([],()=r(require(./page/login/Login.vue ), log in );
const Home=r=require . assure([],()=r(require(./page/Home.vue ), home );
const Forbidden=r=require . assure([],()=r(require(./page/403.vue ),禁止);
const not found=r=require . assure([],()=r(require(./page/404.vue )), not found );
const Dashboard=r=require . assure([],()=r(require(./page/dashboard/Dashboard.vue ), dashboard );
const splash screen=r=require . assure([],()=r(require(./page/splash screen/splash screen . vue ), splash screen );
const add splash screen=r=require . assure([],()=r(require(./page/splash screen/add splash screen . vue ), add splash screen );
常量路由=[
{
路径:“/”,
重定向:“/login”
},{
路径:“/login”,
组件:登录
},{
路径:“/404”,
组件:未找到
},{
路径:“/home”,
成分:家,
重定向:“/home/splashScreen”,
儿童:[
{
路径:“/home/splashScreen”,
组件:防溅屏,
元:{
书名:《国服李白》
}
},{
路径:“/home/addSplashScreen”,
组件:AddSplashScreen,
元:{
题目:吕布,国服
}
}
]
}
];
下面是菜单组件的伪代码。
//sidebar.vue
模板
div class=sidebar
el菜单
.
/el-menu
/div
/模板
脚本
导出默认值{
data() {
返回{
路线:[
{
索引:“1”,
题目:‘国服打野’,
图标:图标字体图标-高光,
儿童:[
{
索引:“闪屏”,
书名:“李白”,
儿童:[]
},
]
},
{
索引:“2”,
头衔:“单身服兵役”,
图标:图标字体图标-推送管理-,
}
]
}
},
方法:{
getLevel(){
const level=session storage . getitem( level );
if(level===0){
this.routes.forEach(函数(值){
If(value.title==国家服务令){
value.hidden=true
value . children . foreach(function(value){
If(value.title==国服关羽){
value.hidden=true
}
})
}
})
}else if(level===1){
this.routes.forEach(函数(值){
value.hidden=true
value . children . foreach(function(value){
value.hidden=true
})
})
}
}
},
已创建(){
this . getlevel();
}
}
/脚本
虽然这样可以实现权限功能,但是有两个问题。
级别存储在会话中,我们可以打开浏览器控制台人为控制级别,这样就失去了权限的意义。
如果我们记住了path,可以直接在浏览器的地址栏手动输入path,然后回车就可以看到任何页面。这也是前端router.js把所有路由都写死的缺点。
这里前端只是通过后端返回的级别来显示/隐藏路由器,所以前端维护整条路由很复杂,隐患很大。
现在我们来谈谈后端控制路由。首先从操作流程上,我们在这里增加了一个仪表盘中间页面,只显示不同级别的一级路线。通过点击对应的一级路由,可以进入对应的页面页面,页面中只显示所有对应的二级路由。
有两个新概念叫做“动态添加路由”和“导航卫士”,就是我的前端router.js只写大家都能访问的路由表,比如login和page 404等。其他所有组件资源都写入一个新的components.js文件,然后components.js中的key通过后端返回的menuData进行映射。如果有相应的密钥,它将被动态添加到路由器中,并通过addRoutes添加。这种添加动态路由的方法应该在每次之前写入导航卫士的hook函数中。
导航卫士是指我在跳转到下一页之前要做的事情。也就是说,登录后,我们会跳转到仪表盘页面。在进入这个页面之前,我们需要重新封装后端请求的menuData,将他返回的数据与我们前端的components.js进行地图匹配,通过addRoutes将最终的数据推送给我们的route。然后我们就可以进入我们的dashborad页面,然后通过dashborad页面进入相应的页面页面,也就是说在dashboard页面进入之前我们就控制了所有的权限。
还有一个小的优化点:当我们通过前面提到的浏览器菜单栏访问非授权页面或者不存在的页面时,需要根据vue-router中的匹配优先级,最终添加Routes 404和*这个页面,这样就可以直接到达404页面,而不是空页。
//components.js所有页面资源
const home=()=import(./page/home . vue’);
const splashScreen=()=import(./page/splash screen/splash screen . vue );
const addSplashScreen=()=import(./page/splash screen/add splash screen . vue’);
const edit splash screen=()=import(./page/splash screen/edit splash screen . vue );
导出默认值{
家,
闪屏,
添加闪屏,
编辑闪屏,
};
//router.js你看,只写通用页面是不是很爽快?
从“Vue”导入Vue;
从“vue-router”导入路由器;
Vue.use(路由器);
const Login=()=import(./page/log in/log in . vue );
const Home=()=import(./page/home . vue’);
const Forbidden=()=import(./page/403 . vue’);
const Dashboard=()=import(./page/dashboard/dashboard . vue );
常量路由=[
{
路径:“/”,
重定向:“/login”
},{
路径:“/login”,
组件:登录
},{
路径:“/403”,
组件:禁止
},
{
路径:“/仪表板”,
组件:仪表板,
},
];
导出默认新路由器({
模式:“历史”,
路线:路线,
基:_ _目录名,
linkActiveClass:“链接活动”
})
//main.js伪代码只保留具体的相关逻辑。
从导入routeMap。/router/component . js ;
const NotFound=()=import(。/page/404 . vue’);
const format routes=function(routes,routeData) {
如果(!routeData) {
routeData={
姓名:家,
路径:“/home”,
//只有组件匹配成功,才能访问特定页面。
组件:routeMap[home],
孩子:[],
};
}
routes . length routes . foreach(route={
if(route.component) {
route . component=route map[route . component];
routeData.children.push({
path: route.path,
名称:route.index,
组件:路由.组件,
元:{
标题:路由。标题,
},
})
}
如果(路线。儿童路线。孩子。长度){
formatRoutes(route.children,routeData);
}
});
返回路由数据
};
设isFetchRemote=true
//使用钩子函数对路由进行权限跳转
router.beforeEach(收件人,发件人,下一个)={
const username=会话存储。getitem(“用户名”);
如果(!用户名to.path!==/login){
接下来({ path:/log in });
}
else if (isFetchRemote to.path!==/login) {
Ajax post(/resource API/getMenuData ).然后(res={
if(参考状态===200参考数据。errno===0){
isFetchRemote=false
常量菜单数据=参考数据。结果;
localStorage.setItem(menudata ,JSON。string ify(菜单数据));
const routeData=格式化路线(菜单数据);
资源应用程序router.addRoutes([routeData]).concat([
{名称:"404",路径:"/404",组件:未找到},
{路径:" * ",重定向:"/404 " }]));
资源应用程序. router.push({
path: to.path,
查询:to.query
});
}
否则{
isFetchRemote=true
}
next();
})。接住(错误={
控制台。日志(错误);
});
}
否则{
next();
}
});
const resourceApp=new Vue({
路由器,
render: h=h(App)
}).$ mount( # app );
//menuData请求数据
//一级菜单与二级菜单的区别是一级菜单带有成分这个值,比如下面的短信管理就是只有一级菜单
{
“errno”:0,
errmsg :获取权限成功,
结果:[
{
索引: 1 ,
标题: 打野位置,
图标:图标字体图标-高光,
儿童:[
{
索引:闪屏,
图标":",
标题: 娜可露露,
路径:/home/splash反转,
组件:防溅,
isShow :对
},
{
索引:添加闪屏,
图标":",
标题: 李白,
路径:/home/add advantage ,
组件:添加不利因素,
isShow: false
},
]
},
{
索引:消息,
标题: 国服上单,
图标:图标字体图标-短西关里,
路径:/home/message ,
组件:消息,
儿童:[
{
索引: addMessage ,
标题: 国服第一关羽,
图标":",
路径:/home/addMessage ,
组件":" addMessage,
isShow: false
}
]
}
]
}
而补充报道和仪表盘这两个组件都只需要通过会议拿到后端的时间就可以。
//仪表板伪代码
模板
div class=nav_list
导航列表 v-for=导航列表中的item @ click= goPage(item)
i :class=item.icon/i
h2{{item.title}}/h2
/div
/div
/模板
脚本
已创建(){
恒定路线arr=JSON。解析(本地存储。getitem(菜单数据);
这个。导航列表=路线安排;
},
方法:{
goPage(项目){
//只有一级菜单
if(item.component){
这个1000美元路由器。推(项。路径);
}否则{
//二级菜单的数据结构中只在孩子们中有小路
这个1000美元路由器。推(项。children[0][ path ]);
}
}
}
/脚本
//侧栏伪代码
脚本
导出默认值{
data() {
返回{
路线:[],
}
},
方法:{
保镖(安排){
返回数组。过滤器(函数(值){
回归!(!val val=== );
});
}
},
已创建(){
const菜单数据=JSON。解析(本地存储。getitem(“菜单数据”);
//通过当前路由器的小路来地图对应的整个路由数组
让路线=菜单数据。映射((项目)={
//只有一级路由
如果(项。组件项目。path==this .$route.path){
console.log(项目)
退货项目;
}否则{
如果(项。children[0][ path ]==this .$route.path){
console.log(项目)
退货项目;
}
}
})
//去掉数组中的undefined、null等空值和假值
this . routes=this . bouncer(routes);
}
}
/脚本
通过这种方式控制权限,如果我们在浏览器控制台中的会话中或者浏览器导航栏中的路径中更改级别,我们都将返回到导航卫士,也就是说,我们将发送重新获取menuData的请求,当我添加Routes时,如果与该值不匹配,我将返回到404。当然,改变等级并不会实现修改权限的控制,因为我们是动态获取路由,而不是之前的前端控制路由。
关于vue的菜单权限控制的样例代码,本文就到这里了。更多关于vue的菜单权限,请搜索我们之前的文章或者继续浏览下面的相关文章。希望你以后能支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。