main.js中的路由守卫
router.beforeEach((to, from ,next)=>{
if(!store.state.token) {
if(to.matched.length > 0 && to.matched[to.matched.length - 1].meta.requireAuth) {
// console.log("不需要登录")
next()
}else{
// console.log("需要登录");
if(to.path == '/login') {
next();
}else{
next("/login")
}
}
}else{
if(!store.state.permissionList) { // 登录过了,没有权限列表, 请求获取权限列表
store.dispatch("SET_PERMISSION").then(()=>{
next({
path: to.fullPath
})
})
}else{
console.log("登录过, 已经有权限列表了")
if(to.path != '/login') {
next();
}else{
next(from.fullPath)
}
}
}
})
路由表中根部暴露出来的路由(实际按自己的路由表写)
export const rootRoutes = [
{
path: '/',
name:'Layout',
component: ()=>import("@/views/layout"),
link: '/',
meta: {
requireAuth: false,
name: 'wrap'
},
children: [
{
path: 'scholl',
name: 'Scholl',
component: ()=>import("@/views/layout/views/scholl/index.vue"),
link: '/scholl',
meta: {
requireAuth: true,
name: '学校'
},
children: [
{
path: 'addScholl',
name: 'AddScholl',
link: '/scholl/addScholl',
component: ()=>import("@/views/layout/views/scholl/views/addScholl/index.vue"),
meta: {
requireAuth: false,
name: '新增学校'
},
},
{
path: 'deleteScholl',
name: 'DeleteScholl',
link: '/scholl/deleteScholl',
component: ()=>import("@/views/layout/views/scholl/views/deleteScholl/index.vue"),
meta: {
requireAuth: true,
name: '删除学校'
}
}
]
},
{
path: 'class',
name: 'Class',
link: '/class',
component: ()=>import("@/views/layout/views/class/index.vue"),
meta: {
requireAuth: false,
name: '班级'
},
children: [
{
path: 'addClass',
name: 'AddClass',
link: '/class/addClass',
component: ()=>import("@/views/layout/views/class/addClass/index.vue"),
meta: {
requireAuth: false,
name: '新增班级'
}
},
{
path: 'deleteClass',
name: 'DeleteClass',
link: '/class/deleteClass',
component: ()=>import("@/views/layout/views/class/deleteClass/index.vue"),
meta: {
requireAuth: true,
name: '删除班级'
}
}
]
}
]
},
// {
// path: '*',
// component: ()=>import("@/views/404")
// }
];
store中的state
export default {
// token
get token() {
return sessionStorage.getItem("token")
},
set token(value) {
sessionStorage.setItem("token", value);
},
// 权限列表
permissionList: null,
// 菜单列表
menuList: []
}
mutation
export default {
// 设置token
SET_TOKEN(state, token) {
state.token = token;
},
// 清空token
CLEAR_TOKEN(state) {
state.token = "";
},
// 设置权限列表
SET_PERMISSIONS(state, permissionList) {
state.permissionList = permissionList;
},
// 清空权限列表
CLEAR_PERMISSIONS(state) {
state.permissionList = null;
},
// 设置菜单列表
SET_MENUS(state, menuList) {
state.menuList = menuList;
},
// 清空菜单列表
CLEAR_MENUS(state, menuList) {
state.menuList = [];
}
}
action中
import { permission } from "@/api"
import router, {rootRoutes} from "@/router"
import { recursionRouters, setDefaultRouter } from "@/utils/handleRouter"
export default {
async SET_PERMISSION({commit, state}, permissionList) {
let data = await permission(state.token),
realRouter = [];
// 写好的路由和请求的路由做比对,得到当前登录人的真实路由权限
realRouter = recursionRouters(data, rootRoutes);
// 添加404页面
realRouter.push({
path: '*',
component: ()=>import("@/views/404")
});
// 设置默认路由
setDefaultRouter(realRouter);
// 路由鉴权
router.addRoute("App", realRouter[0]);
router.addRoute("App", realRouter[1]);
// 存储菜单列表
commit("SET_MENUS", recursivefilter(realRouter[0].children));
// 存储路由权限
commit("SET_PERMISSIONS", realRouter)
// 查看加进去的路由表
console.log(router.getRoutes())
}
}
function recursivefilter(arr) {
return arr.filter(item => {
if (item.meta.white) {
return false
}
if(item.children && item.children.length > 0){
item.children = recursivefilter(item.children)
}
return true
})
}
utils中创建 handleRouterjs文件
// 路由表里面写的路由和后台查询的路由比对,得到当前登录人的真实路由
export function recursionRouters(userRouter=[], allRouter=[]) {
let realRouter = [];
allRouter.forEach(v => {
userRouter.forEach((item, index)=>{
if(item.name == v.meta.name) {
if(item.children && item.children.length > 0) {
v.children = recursionRouters(item.children, v.children);
}
realRouter.push(v);
}
})
});
return realRouter;
}
// 设置默认路由
export function setDefaultRouter(routes) {
routes.forEach((v, i)=>{
if(v.children && v.children.length) {
v.redirect = {name: v.children[0].name}
setDefaultRouter(v.children);
}
})
}
slider组件中
<el-menu :default-active="this.$route.path" class="el-menu-vertical" :collapse="isCollapse" router unique-opened>
<template v-for="(item, index) in menuList"> <!-- menuList缓存在vuex中的菜单列表 -->
<MenuItems :item="item" :key="index"></MenuItems>
</template>
</el-menu>
MenuItems组件中
<el-submenu :index="item.name" v-if="item.children && item.children.length">
<template slot="title">
<i :class="item.meta.icon"></i>
<span slot="title">{{item.meta.name}}</span>
</template>
<template v-for="(innerItem, innerIndex) in item.children" v-if="item.children && item.children.length">
<MenuItems :item="innerItem" :key="innerIndex"></MenuItems>
</template>
</el-submenu>
<template v-else>
<el-menu-item :index="item.link || item.path">
<template slot="title">
<i :class="item.meta.icon"></i>
<span>{{item.meta.name}}</span>
</template>
</el-menu-item>
</template>
// 菜单自定义指令控制显示或隐藏
Vue.prototype.$_hasMenu = function(val) {
if(store.state.buttonList) {
let list = JSON.parse(store.state.buttonList);
for (let i = 0; i < list.length; i++) {
if (list[i].selfIndex == val) {
return true;
}
}
}
return false;
}
Vue.directive("hasMenu", {
inserted: function (el, binding) {
if(!Vue.prototype.$_hasMenu(binding.value)) {
setTimeout(()=>{
el.parentNode && el.parentNode.removeChild(el);
}, 0)
}
}
})
// 递归方法处理
export function recursion(array) {
let parentList = [];
for (let i = 0; i < array.length; i++) {
if (!array[i].parentId) {
parentList.push(array[i]);
}
}
toDoRecursion(parentList);
function toDoRecursion(arr) {
for (let i = 0; i < arr.length; i++) {
let middleArr = [];
for (let j = 0; j < array.length; j++) {
if (arr[i].id == array[j].parentId) {
middleArr.push(array[j]);
}
}
if (middleArr.length != 0) {
toDoRecursion(middleArr);
arr[i].children = middleArr
}
}
}
return parentList;
}