Skip to content

按钮级别权限控制

按钮级别权限控制是在后台系统中很常见的需求,比如:

不同角色只能看到或使用部分按钮,如“新增”、“编辑”、“删除”等

思路

实现核心

让每个按钮都有唯一的权限标识,再根据当前用户的权限列表判断是否显示或禁用

实现

获取权限列表

登录后,获取后端返回的权限列表,使用 Pinia 管理状态

ts
// 假设后端返回
userPermissions = [
  'user:add',
  'user:edit',
  'user:view'
]

// stores/user.ts
import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useUserStore = defineStore('user', () => {
  // 用户权限列表
  const permissions = ref<string[]>([])

  /* 设置权限 */
  function setPermissions(perms: string[]) {
    permissions.value = perms
  }

  /* 判断是否有权限 */
  function hasPermission(code: string): boolean {
    return permissions.value.includes(code)
  }

  return {
    permissions,
    setPermissions,
    hasPermission,
  }
})

使用自定义指令

定义自定义指令,添加判断逻辑

ts
// directives/permission.ts
import type { App } from 'vue'
import { useUserStore } from '@/stores/user'

export function hasPermi(app: App<Element>) {
  app.directive('hasPermi', (el, binding) => {
    const { value } = binding
    const userStore = useUserStore()

    if (value && typeof value === 'string') {
      const hasPermission = hasPermission(value)
      if (!hasPermission) {
        // 移除按钮
        el.parentNode && el.parentNode.removeChild(el)
        // 禁用按钮
        // el.disabled = true
        // el.classList.add('is-disabled')
      }
    } else {
      console.error('请设置操作权限标签值')
    }
  })
}

// 通用权限常量
const ALL_PERMISSION = '*:*:*'
/* 判断权限的方法 */
export const hasPermission = (permission: string[]): boolean => {
  const userStore = useUserStore()
  const perms = userStore.permissions

  return (
    perms.includes(ALL_PERMISSION) ||
    permission.some(permission => perms.includes(permission))
  )
}

main.ts 中注册:

ts
hasPermi(app)

使用示例

按钮上使用指令:

vue
<template>
  <div>
    <button v-hasPermi="['user:add']">新增用户</button>
    <button v-hasPermi="['user:edit', 'user:update']">编辑用户</button>
  </div>
</template>

如有转载请标注本站地址