vue 前端控制路由权限,分角色控制菜单。
- 流程说明
- 首先说明,这个路由控制权限全是在前端做的。
- 流程==》用户登录》存储用户角色和登陆标志》在加载左侧菜单时时根据用户角色类型去筛选。
- 项目结构
//home文件为主框架
- 代码展示
router/index.js文件
import Vue from 'vue'
import Router from 'vue-router'
const Home = () => import('@/components/Home') //主菜单
const login = () => import('@/components/Login') //登陆
const baseUpload =()=> import('@/components/baseUpload')//数据导入
const UserList = () => import('@/components/view/user/UserList') //会员列表
const UserPage = () => import('@/components/view/user/UserPage') //个人主页
Vue.use(Router)
/*
* @Author: baiyf
* @Date: 2019-05-13 13:23:44
* @Description: 参数说明
* hidden true不在左侧菜单展示,false反之;
* leaf true表示只有一没有节点,只有父级,false反之;
* userTypeArry 设计为数组类型,1为最高权限,2为二等权限,3为客服权限 123合体则为通用权限 以此类推
*/
export default new Router({
routes: [
//此路由位置,谁排在前面先加载谁
{
path: '/',
redirect: '/login',
hidden:true,
userTypeArry:['1','2','3']
},
{
path: '',
name: '会员管理',
component: Home,
userTypeArry:['1','2','3'],
iconCls: 'el-icon-user-solid',
children: [
{ path: '/UserList', component: UserList, name: '会员列表',},
{ path: '/UserPage', component: UserPage, name: '个人主页',hidden:true},
]
},
{
path: '',
name: '',
component: Home,
userTypeArry:['1','2','3'],
iconCls: 'el-icon-document-add',
hidden:true,
children: [
{ path: '/baseUpload', component: baseUpload, name: '数据导入',hidden:true },
]
},
]
});
//读取路由表生成左侧菜单 home.vue 页面中可以通过 $router.options.routes 拿到路由信息,然后对其遍历处理
<el-aside style="height:100%;background:#ffffff">
<el-row class="tac">
<!--强行加入动画过度隐藏效果-->
<transition name="el-fade-in">
<el-menu :default-active="$route.path" class="el-menu-vertical-demo" unique-opened router
@open="handleOpen" v-if="!isCollapse" @close="handleClose" :collapse="isCollapse"
:class="{'isCollapseFalseStyle':isCollapse!=true}">
<template v-for="(item,index) in $router.options.routes" v-if="!item.hidden">
<!--leaf 有子项的菜单 用el-submenu标签 查看权限中是否有登录单位的类型-->
<el-submenu :index="index+''" v-if="!item.leaf && item.userTypeArry.indexOf(userType) != -1" >
<!--大菜单标题-->
<template slot="title">
<i :class="item.iconCls"></i>
<span slot="title">{{item.name}}</span>
</template>
<!--小菜单-->
<el-menu-item v-for="child in item.children" :index="child.path" :key="child.path"
v-if="!child.hidden">{{child.name}}</el-menu-item>
</el-submenu>
<!--没有子项的菜单 单个的用el-menu-item-->
<el-menu-item v-if="item.leaf && item.children.length==1 && item.userTypeArry.indexOf(userType) != -1" :index="item.children[0].path" >
<i :class="item.iconCls"></i>
<span slot="title"> {{item.children[0].name}}</span>
</el-menu-item>
</template>
</el-menu>
</transition>
</el-row>
</el-aside>
//这个时候虽然对路由表进行了遍历,对其个别进行隐藏和显示,但是当用户在地址栏里面输入本不是他权限的地址,仍然可以访问,所以要做路由处理 在main.js中
router.beforeEach((to, from, next) => {
let flag=window.sessionStorage.getItem("flag");
let userType=window.sessionStorage.getItem("userType");
var handlePath;
if(to.fullPath.indexOf("?")!="-1"){ //有参数
handlePath = to.fullPath.substr(0,to.fullPath.indexOf("?"));
}else{ //无参数
handlePath = to.fullPath;
}
if(to.fullPath=="/login" || to.fullPath=="/ErrorMiss" || to.fullPath=="/UpLoad"){
next();
}else{
if(flag){//flag为登录标志
let f=false;
routerInfo.filter((item)=>{
if(item.userTypeArry.indexOf(userType) != "-1"){ //判断登陆类型是否与权限数组中的类型相吻合 然后判断要去的path是否存在
if(item.children){ //当有子节点时
if(item.children.length>1){ //当节点大于1时 进行循环便利;
for(let i=0;i<item.children.length;i++){
if(handlePath == item.children[i].path){
f=true;
}
}
}else{ //当节点等于于1;
if(handlePath == item.children[0].path){
f=true;
}
}
}else{ //当没有子节点时
if(handlePath == item.path){
f=true;
}
}
}
return f;
});
if(f){
next();
}else{
next("/ErrorMiss");
console.error("已登陆,但是要去的路由属于无权限查看路由或者不存在的路由,重定向404");
}
}else{
next("/login");
console.error("还未登陆,重定向到登陆页面!");
}
}
})
这就是大致流程,主要就是前端处理。随后会做一个路由表由后端返回的功能