vue3封装自定义指令,根据权限判断页面按钮可不可以点击

27 阅读1分钟

image.png

image.png

image.png

// src/directives/permission.js
import { usePermissionStore } from '@/store/modules/permission'
 
export const permissionDirective = {
  mounted(el, binding) {
    const permissionStore = usePermissionStore()
    const { value } = binding
    
    if (value && Array.isArray(value)) {
      // 检查是否有权限
      const hasPermission = permissionStore.hasPermission(value)
      if (!hasPermission) {
        el.parentNode?.removeChild(el)
      }
    } else {
      throw new Error(`需要权限数组,如 v-permission="['add']"`)
    }
  }
}
import { defineStore } from 'pinia'
 
export const usePermissionStore = defineStore('permission', {
  state: () => ({
    permissionData: null, // 存储原始权限数据
    authorizedRoutes: [], // 过滤后的前端路由
  }),
 
  actions: {
    setPermissionData(data) {
      this.permissionData = data
    },
 
    setAuthorizedRoutes(routes) {
      this.authorizedRoutes = routes
    },
 
    clearSessionData() {
      this.permissionData = null
      this.authorizedRoutes = []
    },
 
    // 检查是否有权限
    hasPermission(permissions) {
      if (!this.permissionData) return false
 
      // 递归检查权限树
      const checkPermission = (nodes, codes) => {
        return nodes.some((node) => {
          if (codes.includes(node.webPath)) return true
          if (node.children?.length) {
            return checkPermission(node.children, codes)
          }
          return false
        })
      }
 
      return checkPermission(this.permissionData.permissionTree, permissions)
    },
  },
})
 
export default usePermissionStore
// src/main.js
import { createApp } from 'vue'
import { permissionDirective } from './directives/permission'
 
const app = createApp(App)
 
// 注册指令
app.directive('permission', permissionDirective)
 
app.mount('#app')
<template>
  <!-- 只有有add权限才会显示 -->
  可以每个页面加各自的标识:corn-add
  <button v-permission="['add']">创建任务</button>
  
  <!-- 多个权限满足其一即可 -->
  <button v-permission="['add', 'edit']">操作按钮</button>
</template>