# 定义router.js
- 引入官方layout组件
- 创建权限要求基页
- 创建权限要求界面
- 注册路由
- 写一些公用路由方法
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404.vue'),
hidden: true
},
]
export const asyncRoutes = [
//用户信息路由
{
path: '/user',
component: Layout,
redirect: '/user',
name: 'User',
meta: { title: '用户管理', icon: 'el-icon-s-help' },
children: [
{
path: 'userInfo',
name: 'userInfo',
component: () => import('@/views/user/user'),
meta: { title: '小程序用户', icon: 'table' }
},
{
path: 'adminUserInfo',
name: 'adminUserInfo',
component: () => import('@/views/user/adminUserInfo'),
meta: { title: '管理员用户', icon: 'table' ,roles: [ 'editor']} // 您可以在根导航中设置角色}
},
]
},
]
//这里显示设置显示普通用户可以看到的路由
const createRouter = () => new Router({
// mode: 'history', // require service support
//scrollBehavior这是封装的一个路由守卫
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 再permission.js中加入路由守卫(根目录下)
每次路由跳转判断权限
调用Vuex种方法提交判断需求
await store.dispatch('user/getInfo')
const roles = store.state.user.permList;
// generate accessible routes map based on roles
// root: A module use B module's function
const accessRoutes = await store.dispatch('permissions/generateRoutes', roles)
1
2
3
4
5
2
3
4
5
- 读取出当前用户可以加载的路由 后判断当前路由表 做校验如果没有则插入(这里可以做判断如果有多余的要删除)
try {
// get user info (vuex-modules)
await store.dispatch('user/getInfo')
const roles = store.state.user.permList;
// generate accessible routes map based on roles
// root: A module use B module's function
const accessRoutes = await store.dispatch('permissions/generateRoutes', roles)
// dynamically add accessible routes
console.log(accessRoutes);
console.log(router);
await router.addRoutes(accessRoutes);
console.log(router);
// this.$router.options.routes = this.$router.options.routes.concat(newRoutes);
next({ ...to, replace: true })
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
// Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- 这里的判断也可以学一下如果当前页面下没有权限 跳转404 重新进入后用redirect跳转回来
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
// Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
1
2
3
4
5
2
3
4
5
# 权限判断放到了store.modules.permissions
- 判断路由中的meta中是否有meta字段 如果有则判断没有则直接显示
/**
* Use meta.role to determine if the current user has permission
* @param roles
* @param route
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 同时过滤 他的children路由如果有则深度一直遍历下去
/**
* Filter asynchronous routing tables by recursion
* @param routes asyncRoutes
* @param roles
*/
export function filterAsyncRoutes(routes, roles) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (hasPermission(roles, tmp)) {
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 将过滤出来的路由返回并放置到vuex中
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
console.log(accessedRoutes);
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 注意左侧索引栏
因为索引栏是根据router.options.routes来渲染的,Vue的addRouter api 不会自动将路由加到options中所以尽量用vuex来控制这里只是简单的实现一下。
# 按钮级别
- 定义permission.js(store就是单纯的取出权限列表)
import store from '@/store'
/**
* Filter asynchronous routing tables by recursion
* @param el current element
* @param binding all value
*/
function checkPermission(el, binding) {
const { value } = binding
const roles = store.getters && store.getters.router
if (value && value instanceof Array) {
if (value.length > 0) {
const permissionRoles = value
const hasPermission = roles.some(role => {
if(role === 'admin'){
return true;
}else{
return permissionRoles.includes(role)
}
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
}
} else {
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
}
}
export default {
// when this directive insert/update all use this method
inserted(el, binding) {
checkPermission(el, binding)
},
update(el, binding) {
checkPermission(el, binding)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
- 单个页面引入
import permission from './permission'
const install = function(Vue) {
Vue.directive('permission', permission)
}
if (window.Vue) {
window['permission'] = permission
Vue.use(install); // eslint-disable-line
}
permission.install = install
export default permission
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
import permission from '@/directive/permission/index.js' // 权限判断指令
import rowClass from "../mixin/rowClass.mixin"
export default {
name: "Device",
mixins: [rowClass],
directives: { permission },
1
2
3
4
5
6
2
3
4
5
6
- 整体引入