Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue要做权限管理该怎么做?控制到按钮级别的权限怎么做? #118

Open
GGXXMM opened this issue Mar 23, 2022 · 0 comments
Open
Labels

Comments

@GGXXMM
Copy link
Owner

GGXXMM commented Mar 23, 2022

权限管理

image
Vue权限管理可以分为4个方面:

  1. 接口权限
  2. 路由权限
  3. 菜单权限
  4. 按钮权限

接口权限

接口请求验证 token,当 token 无效时,接口无权限访问,页面重定向跳转至登录页登录。

路由权限

用户登录,有权限访问的路由,即为路由权限控制。
方案1:
初始化挂载全部的路由,路由配置再添加 roles 有权访问的角色。

  {
    path: '/permission',
    component: Layout,
    redirect: '/permission/index',
    alwaysShow: true, // will always show the root menu
    meta: {
      title: 'permission',
      icon: 'lock',
      roles: ['admin', 'editor'] // you can set roles in root nav
    },
    children: [{
      path: 'page',
      component: () => import('@/views/permission/page'),
      name: 'pagePermission',
      meta: {
        title: 'pagePermission',
        roles: ['admin'] // or you can only set roles in sub nav
      }
    }, {
      path: 'directive',
      component: () => import('@/views/permission/directive'),
      name: 'directivePermission',
      meta: {
        title: 'directivePermission'
        // if do not set roles, means: this page does not require permission
      }
    }]
  }]

缺点:
1) 初始化时,需要加载所有的路由,如果路由很多,对性能会有一定影响
2)全局路由守卫,每次路由跳转都要做权限判断
3)菜单跟路由耦合在一起,定义路由的时候需要添加菜单字段标识(菜单标题、图标之类的信息)
4)菜单信息写死在前端,该个菜单标题或权限信息,需要重新编译打包

方案2:
初始化先挂载不需要权限控制的路由,比如登录页、404等错误页。登录后,获取用户的权限信息,然后筛选有权限访问的路由,在全局路由守卫里调用 addRoutes 动态添加路由即可。
image

优点:
初始化时,不用加载所有路由。
缺点:
同方案1的后3个缺点一致。

菜单权限

方案1:
菜单与路由分离,菜单由后端接口返回。

缺点:
1)菜单需要与路由做一一对应,添加新菜单,需要本地配置路由与之对应。
2)全局路由守卫里,每次路由跳转都要做判断。

方案2:
菜单和路由都由后端接口返回。

缺点:
1)全局路由守卫里,每次路由跳转都要做判断。
2)前后端配合度要求更高。

按钮权限控制如何做?

方案一:v-if判断:用户权限role和路由表里的 meta.btnPermissions 匹配判断。

{
    path: '/permission',
    component: Layout,
    name: '权限测试',
    meta: {
        btnPermissions: ['admin', 'supper', 'normal']
    },
    //页面需要的权限
    children: [{
        path: 'supper',
        component: _import('system/supper'),
        name: '权限测试页',
        meta: {
            btnPermissions: ['admin', 'supper']
        } //页面需要的权限
    },
    {
        path: 'normal',
        component: _import('system/normal'),
        name: '权限测试页',
        meta: {
            btnPermissions: ['admin']
        } //页面需要的权限
    }]
}

方案二:自定义指令 v-permission

1)定义权限鉴定指令

/**权限指令**/
const permission = Vue.directive('has', {
    bind: function (el, binding, vnode) {
        // 获取页面按钮权限(接口获取:当前用户登录的权限节点数组)
        let btnPermissionsArr = [];
        if(binding.value){
            // 如果指令传值,获取指令参数,根据指令参数和当前登录人按钮权限做比较。
            btnPermissionsArr = Array.of(binding.value);
        }else{
            // 否则获取路由中的参数,根据路由的btnPermissionsArr和当前登录人按钮权限做比较。
            btnPermissionsArr = vnode.context.$route.meta.btnPermissions;
        }
        if (!Vue.prototype.$_has(btnPermissionsArr)) {
            el.parentNode.removeChild(el);
        }
    }
});
// 按钮权限判断
Vue.prototype.$_has = function (value) {
    let isExist = false;
    // 获取当前按钮权限code
    let btnPermissionsCode = sessionStorage.getItem("btnPermissions");
    if (btnPermissionsCode == undefined || btnPermissionsCode == null) {
        return false;
    }
    if (value.indexOf(btnPermissionsCode) > -1) {
        isExist = true;
    }
    return isExist;
};

2)按钮引用 v-permission 指令

<el-button @click='editClick' type="primary" v-permission>编辑</el-button>

3)优化:
接口返回的权限节点 Array 可以使用 Set 存储优化。

Set 优点:
a. Set 查询性能比 indexOf 高,时间复杂度为O(1)
b. Set 可以去除重复元素

@GGXXMM GGXXMM added the vue label Apr 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant