后台管理系统权限管理

后台管理系统权限管理

最后修改时间:a month ago

# 定义router.js

  1. 引入官方layout组件
  2. 创建权限要求基页
  3. 创建权限要求界面
  4. 注册路由
  5. 写一些公用路由方法
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

# 再permission.js中加入路由守卫(根目录下)

  1. 每次路由跳转判断权限 在这里插入图片描述

  2. 调用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
  1. 读取出当前用户可以加载的路由 后判断当前路由表 做校验如果没有则插入(这里可以做判断如果有多余的要删除)
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
  1. 这里的判断也可以学一下如果当前页面下没有权限 跳转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

# 权限判断放到了store.modules.permissions

  1. 判断路由中的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
  1. 同时过滤 他的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
  1. 将过滤出来的路由返回并放置到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

# 注意左侧索引栏

因为索引栏是根据router.options.routes来渲染的,Vue的addRouter api 不会自动将路由加到options中所以尽量用vuex来控制这里只是简单的实现一下。 在这里插入图片描述

# 按钮级别

  1. 定义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
  1. 单个页面引入
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
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
  1. 整体引入 在这里插入图片描述
- 全文完 -

留下一条留言?
默认颜色

主题颜色

标准颜色

更多颜色...