TypeScript & Js Array简要实现角色权限的页面级控制

学习 · 2022-03-23

QQ截图20220323205512.png

角色权限控制

技术要点

  • Vuejs的自定义指令
  • JavaScript基础知识
  • Js Array基础知识
  • Type Script 基础语法变量类型

代码实现

  • 主要就是得到用户的rolesauthorities
  • 通过对比指令集跟用户存在的数据校验,存在即通过
/**
 * 按钮级权限控制
 */
import type { App } from 'vue';
import { useUserStore } from '@/store/modules/user';
// 数据范例
// useUserStore: {
//     roles: ['super', 'admin'],
//     authorities: ['system:user:add','system:user:list','system:user:update','system:user:remove']
// }

// 校验范例
// <button v-role="['admin']">删除</button>
// <button v-any-role="['admin']">删除</button>
// <button v-permission="['system:user:remove']">删除</button>
// <button v-any-permission="['system:user:remove']">删除</button>

// 判断数组是否有某些值
const arrayHas = function (
  array: (string | undefined)[],
  value: string | string[]
): boolean {
  if (!value) {
    return true;
  }
  if (!array) {
    return false;
  }
  if (Array.isArray(value)) {
    for (let i = 0; i < value.length; i++) {
      if (array.indexOf(value[i]) === -1) {
        return false;
      }
    }
    return true;
  }
  return array.indexOf(value) !== -1;
};

// 判断数组是否有任意值
const arrayHasAny = function (
  array: (string | undefined)[],
  value: string | string[]
): boolean {
  if (!value) {
    return true;
  }
  if (!array) {
    return false;
  }
  if (Array.isArray(value)) {
    for (let i = 0; i < value.length; i++) {
      if (array.indexOf(value[i]) !== -1) {
        return true;
      }
    }
    return false;
  }
  return array.indexOf(value) !== -1;
};

/**
 * 是否超级管理员
 * @param value 角色字符或字符数组
 */
function hasSuper(roles: (string | undefined)[]): boolean {
  return arrayHas(roles, 'super');
}

/**
 * 是否有某些角色
 * @param value 角色字符或字符数组
 */
export function hasRole(value: string | string[]): boolean {
  const userStore = useUserStore();
  return arrayHas(userStore?.roles, value) || hasSuper(userStore?.roles);
}

/**
 * 是否有任意角色
 * @param value 角色字符或字符数组
 */
export function hasAnyRole(value: string | string[]): boolean {
  const userStore = useUserStore();
  return arrayHasAny(userStore?.roles, value) || hasSuper(userStore?.roles);
}

/**
 * 是否有某些权限
 * @param value 权限字符或字符数组
 */
export function hasPermission(value: string | string[]): boolean {
  const userStore = useUserStore();
  return arrayHas(userStore?.authorities, value) || hasSuper(userStore?.roles);
}

/**
 * 是否有任意权限
 * @param value 权限字符或字符数组
 */
export function hasAnyPermission(value: string | string[]): boolean {
  const userStore = useUserStore();
  return (
    arrayHasAny(userStore?.authorities, value) || hasSuper(userStore?.roles)
  );
}

export default {
  install(app: App) {
    // 添加自定义指令
    app.directive('role', {
      mounted: (el, binding) => {
        if (!hasRole(binding.value)) {
          el.parentNode?.removeChild(el);
        }
      }
    });
    app.directive('any-role', {
      mounted: (el, binding) => {
        if (!hasAnyRole(binding.value)) {
          el.parentNode?.removeChild(el);
        }
      }
    });
    app.directive('permission', {
      mounted: (el, binding) => {
        if (!hasPermission(binding.value)) {
          el.parentNode?.removeChild(el);
        }
      }
    });
    app.directive('any-permission', {
      mounted: (el, binding) => {
        if (!hasAnyPermission(binding.value)) {
          el.parentNode?.removeChild(el);
        }
      }
    });
  }
};

使用

// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import permission from './utils/permission';
const app = createApp(App);
// use
app.use(permission);
app.mount('#app');
array javascript 角色权限 typescript 权限控制
Theme Jasmine by Kent Liao | 桂ICP备15008025号-6