路由的设置会根据系统中用户角色的数量而有所不同,大致分为三种单角色同权限、单角色不同权限、多角色。这里的角色均是只一种身份,而不是用户量。接下来的讲解纯属个人见解,大型项目会将不同权限的用户直接分开开发不同的系统。如果是小型多角色项目可以采用我的这个办法。
先说一说大致分类:
- 单角色同权限
- 只有一种角色,这种角色对每一个组件的权限还相同。
- 这种直接采用静态路由即可,并且由于权限的固定路由守卫验证起来也没有那么繁杂。
- 单角色不同权限
- 有一种角色,但是这种角色之间有着不同的权限
- 这种常采用路由跟着用户走的设计,也就是用户用到什么路由,系统就加载什么路由
- 多角色
- 一个系统有多种角色
- 多种角色权限不同,位于一个系统
- 这种常采用动态路由,并且将不同用户路由进行详细划分
这里我着重说一下多角色的这一个系统
路由的设置如下目录:
index.js中主要存放一些所有用户均会用到的插件,以及对路由对象的初始化。(在进行完之后,将其暴露出去)
import VueRouter from "vue-router";
import Layout from "../views/Layout/index"
import Login from "../views/Login/index"
// import store from "./store/index.js"
// 基础的路由规则不受限制
const router = new VueRouter({
routes: [
{
name:"home",
path: "/",
component: Layout,
meta: {
// 用于控制,只要是我们项目中的路由都可以查到这个信息
isOurProject: true
},
children: []
},
{
// 如果验证没有登录的话就跳转到登录页面
path: "/login",
component:Login
},
// 配置在最下面,可以守卫防止用户乱窜
{
name: "404",
path: "*",
component: () => import("../components/Nofind")
}
]
})
export default router
在routeguard.js文件中将index.js导入并配置路由守卫,这里使用
router.addRoute(“home”, routeRule[0])将不同角色相关的路由进行动态加入并挂载在响应角色的home目录下。
component:()=>import(“…/views/Student/index”),是对组件进行异步加载。
const pathDic = { “1”: “/student”, “2”: “/teacher”, “3”: “/admin” }是三种用户对应的不同路径,这里还有一个tag(值为1,2,3分别代表学生、老师、管理员,正好在这个字典内作为键,用户获取后续的值)。
在登录的时候会根据用户的选择进行身份验证验证通过后使用编程式路由跳转向响应的路由,然后在路由守卫中进行比对将对应路由动态加载一下。由此区分同一系统中的不同角色。
import router from "./index"
import store from "../store/index"
//三种用户所对的路由(负责映射动态路由)
const pathDic = { "1": "/student", "2": "/teacher", "3": "/admin" }
//路由规则
const routers = [
{
// 学生页面
name: "student",
path: "/student",
component:()=>import("../views/Student/index"),
redirect:"/student/home",
children:[
{
name:"studenthome",
path:"home",
component:()=>import("../components/Home")
},
{
name:"tem",
path:"tem",
component:()=>import("../components/XtermTerminal"),
meta:{
keepAlive:true
}
} ,
{
// 简写(管理员管理学生)
name: "test",
path: "test",
component: () => import("../views/Admin/Test")
},
{
name:"container",
path:"Container",
component:()=>import("../views/Student/Container")
},
{
name:"ccontainer",
path:"ccontainer",
component:()=>import("../pages/Other/customContainer")
},
]
},
{
name: "teacher",
path: "/teacher",
component:()=>import("../views/Teacher/index"),
redirect:"/teacher/home",
children:[
{
name:"teacherhome",
path:"home",
component:()=>import("../views/Teacher/TeacherHome")
},
{
name:"c1",
path:"container",
component:()=>import("../pages/Other/Container")
},
{
name:"ccontainer",
path:"ccontainer",
component:()=>import("../pages/Other/customContainer")
},
{
name:"rcontainer",
path:"rcontainer",
component:()=>import("../pages/Other/readyContainer")
}
]
},
{
//管理员页面
name: "admin",
path: "/admin",
component: () => import("../views/Admin/index"),
redirect:"/admin/home",
children: [
{
name:"adminhome",
path:"home",
component:()=>import("../components/Home")
},
{
// 简写(管理员管理学生)
name: "ams",
path: "manageStudent",
component: () => import("../pages/Student/ManageStudent")
},
{
// 简写(管理员增加学生)
name: "aas",
path: "addStudent",
component: () => import("../pages/Student/addStudent")
},
{
// 简写(管理员管理学生)
name: "test",
path: "test",
component: () => import("../views/Admin/Test")
},
{
name: "amt",
path: "manageteacher",
component: () => import("../pages/Teacher/ManageTeacher")
},
{
name:"tem",
path:"tem",
component:()=>import("../components/XtermTerminal"),
meta:{
keepAlive:true
}
}
]
}
]
router.beforeEach((to, from, next) => {
//读取vuex中的用户基本信息
let tempname = store.state.loginModel.userInfo.userName
let temptag = store.state.loginModel.userInfo.tag
if (!tempname) {
//防止用户恶意修改路由
if (to.path !== "/login") next("/login")
else return next()
} else {
// 首次进入的话会进行动态路由加载
if (!store.state.loginModel.isLogin) {
const routeRule = routers.filter(item => {
return item.path === pathDic[temptag]
})
router.addRoute("home", routeRule[0])
store.commit('loginModel/alertIsLogin')
return next(pathDic[temptag])
}
if (to.path == "/login") next(pathDic[temptag])
else if (to.path == "/") next(pathDic[temptag])
else {
next()
}
}
})
router.afterEach((to, from) => {
// eslint-disable-next-line no-console
// console.log(to,from)
from
document.title = to.meta.title || "默认页签"
})
在进行路由动态加载时可能会抛出警告。
解决方法如下(将警告捕获并忽略):
if (tag === 1) {
this.$router.replace("/student").catch(() => {});
} else if (tag === 2) {
this.$router.replace("/teacher").catch(() => {});
} else {
this.$router.replace("/admin").catch(() => {});
}