Skip to content

按钮权限 ​

ProTable 支持与后台权限体系对接,根据权限码控制工具栏按钮(添加、删除、返回)和操作列按钮(编辑、复制、删除)的显示与隐藏。不接入权限时行为与原来一致,仅由 showAdd、showEdit 等配置控制。


使用方式概览 ​

  1. 在应用入口注入权限校验函数 hasPermission,由 ProTable 在渲染按钮前调用。
  2. 在表格配置里为各按钮指定权限码(如 user:add、user:delete),有权限时才显示对应按钮。

组件内部不依赖具体权限库或指令,只要你在全局提供 hasPermission 并在配置里写上权限码即可。


一、全局注入 hasPermission ​

在安装时传入 hasPermission,通常与项目里已有的权限逻辑(如 Pinia、指令 v-permission)共用同一套判断。

配置位置 ​

在 app.use(AdminProTable, options) 的 options 中增加:

属性说明类型
hasPermission权限校验函数:传入权限码(单个或数组),返回是否拥有权限;未提供则不启用权限控制(code: string | string[]) => boolean

参数与返回值 ​

  • 参数 code:单个权限码(如 'user:add')或权限码数组(如 ['user:add', 'user:edit'])。 传数组时,有任一权限即视为通过(常用于「多角色任一可操作」的场景)。
  • 返回值:true 表示有权限,按钮显示;false 表示无权限,按钮不显示。

时序说明:权限数据是接口返回的怎么办? ​

hasPermission 只是在 main.js 中注册一个函数引用,注册时并不执行。组件渲染按钮时才会调用它,此时权限数据已经通过登录/路由守卫加载完毕。所以不存在时序问题,正常写即可。

典型流程:

1. main.js:app.use(AdminProTable, { hasPermission })  ← 只存函数,不执行
2. 用户登录:请求接口拿到权限列表,存入 Pinia store
3. 页面渲染表格按钮:组件调用 hasPermission('user:add')
                      → 此时从 store 读权限列表 → 正常返回

示例:与 Pinia Store 对接(推荐) ​

js
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import AdminProTable from 'admin-pro-table'
import { useUserStore } from '@/stores/user'

const app = createApp(App)

app.use(AdminProTable, {
  hasPermission(codes) {
    // 渲染时才调用,此时 store 里的权限已加载完毕
    const store = useUserStore()
    const list = Array.isArray(codes) ? codes : [codes]
    return list.some((code) => code && store.permissions.includes(code))
  }
})

app.mount('#app')
js
// router/index.js — 路由守卫中加载权限
router.beforeEach(async (to) => {
  const store = useUserStore()
  if (isLoggedIn() && !store.permissions.length) {
    await store.fetchPermissions()  // 请求接口,把权限列表存入 store
  }
})

示例:不用 Pinia,用工具函数 ​

js
// utils/permission.js
let _permissions = []

export function setPermissions(list) {
  _permissions = list
}

export function hasPermission(codes) {
  const list = Array.isArray(codes) ? codes : [codes]
  return list.some((code) => code && _permissions.includes(code))
}
js
// main.js
import { hasPermission } from '@/utils/permission'

app.use(AdminProTable, { hasPermission })
js
// 登录成功后
import { setPermissions } from '@/utils/permission'

const res = await login()
setPermissions(res.permissions)  // 写入后,hasPermission 就能读到了

示例:与项目内 v-permission 同源 ​

若项目里已有 v-permission 或 hasPermi,让 hasPermission 调用同一套逻辑即可:

js
import { hasPermi } from '@/utils/permission'  // 与 v-permission 同源

app.use(AdminProTable, {
  hasPermission(codes) {
    const list = Array.isArray(codes) ? codes : [codes]
    return list.some((code) => code && hasPermi(code))
  }
})

说明:未传入 hasPermission 时,不做权限判断,仅根据 showXxx、xxxPermission 配置决定是否显示按钮;若传了 hasPermission 且配置了权限码,则「配置显隐」与「权限显隐」同时满足才显示。


二、工具栏按钮权限码 ​

工具栏包含「返回」「添加」「删除」等内置按钮,通过 tableConfig.toolbarConfig 配置是否显示及对应的权限码。

配置项 ​

在 表格配置 的 toolbarConfig 中,除原有 showBack、showAdd、showDelete 外,可增加以下可选权限码(不传则只按 showXxx 控制):

属性说明类型默认值
addPermission添加按钮权限码;传入且已配置全局 hasPermission 时,有权限才显示添加按钮string | string[]-
deletePermission批量删除按钮权限码;同上string | string[]-
backPermission返回按钮权限码;同上string | string[]-
  • string:单个权限码,如 'user:add'。
  • string[]:多个权限码,有任一即显示按钮,如 ['user:add', 'admin:add']。

显示逻辑简述 ​

  • 未配置 hasPermission 或未配置对应 xxxPermission:只根据 showBack / showAdd / showDelete 及 formConfig、deleteConfig 等决定是否显示。
  • 配置了 hasPermission 且配置了 xxxPermission:在原有“是否显示”条件基础上,再与 hasPermission(xxxPermission) 做与运算,两者都满足才显示。

示例 ​

js
const tableConfig = {
  toolbarConfig: {
    showAdd: true,
    showDelete: true,
    addPermission: 'user:add',      // 有 user:add 才显示「添加」
    deletePermission: 'user:delete' // 有 user:delete 才显示「删除」
  },
  // ...
}

三、操作列按钮权限码 ​

操作列包含「编辑」「复制」「删除」等内置按钮,通过 tableConfig.operationConfig 配置是否显示及对应的权限码。

配置项 ​

在 附加列配置 的 operationConfig 中,除原有 showEdit、showDelete、showCopy 外,可增加以下可选权限码:

属性说明类型默认值
editPermission编辑按钮权限码;可为函数 (row) => string | string[],按行区分权限string | string[] | ((row) => string | string[])-
deletePermission删除按钮权限码;同上string | string[] | ((row) => string | string[])-
copyPermission复制按钮权限码;同上string | string[] | ((row) => string | string[])-
  • string / string[]:整表统一权限码,或「任一即可」的多个码。
  • 函数 (row) => string | string[]:根据当前行数据返回权限码,用于「按行控制」(如根据行内角色、状态决定是否可编辑/删除)。

显示逻辑简述 ​

与工具栏类似:在原有 showEdit / showDelete / showCopy(及行级函数)基础上,若配置了 hasPermission 与对应 xxxPermission,再与 hasPermission(editPermission(row)) 等结果做与运算。

示例:整表统一权限码 ​

js
const tableConfig = {
  operationConfig: {
    width: 200,
    editPermission: 'user:edit',
    deletePermission: 'user:delete',
    copyPermission: 'user:copy'
  }
}

示例:按行区分权限码 ​

例如仅「创建人」可编辑、仅「未发布」可删除:

js
const tableConfig = {
  operationConfig: {
    editPermission: (row) => row.isCreator ? 'user:edit' : '',
    deletePermission: (row) => row.status === 'draft' ? 'user:delete' : ''
  }
}

四、与指令 v-permission 的配合 ​

  • 内置按钮:通过上面的 hasPermission + 权限码即可控制,无需在组件内部使用 v-permission。只要你的 hasPermission 与项目里 v-permission 使用同一套权限数据(如同一 store 或同一工具函数),表现就会一致。
  • 自定义按钮:若在插槽里自己写按钮,可直接使用 v-permission:
    • 工具栏:toolbar、toolbar-before、toolbar-after
    • 操作列:operation-before、operation-after

这样内置按钮用「配置 + hasPermission」,自定义按钮用指令,两套方式可以并存。


五、完整示例 ​

入口注入 hasPermission ​

js
// main.js
import { createApp } from 'vue'
import AdminProTable from '@your/admin-pro-table'

const mockCodes = ['user:add', 'user:edit', 'user:delete', 'user:copy'] // 演示用

const app = createApp(App)
app.use(AdminProTable, {
  hasPermission(codes) {
    const list = Array.isArray(codes) ? codes : [codes]
    return list.some((c) => c && mockCodes.includes(c))
  }
})
app.mount('#app')

页面中配置权限码 ​

vue
<template>
  <pro-table
    :search-config="searchConfig"
    :table-config="tableConfig"
    :form-config="formConfig"
  />
</template>

<script setup>
import { reactive } from 'vue'

const tableConfig = reactive({
  requestConfig: { api: getList },
  deleteConfig: { api: deleteItem, idField: 'id', paramKey: 'id' },
  columns: [/* ... */],
  toolbarConfig: {
    showAdd: true,
    showDelete: true,
    addPermission: 'user:add',
    deletePermission: 'user:delete'
  },
  operationConfig: {
    editPermission: 'user:edit',
    deletePermission: 'user:delete',
    copyPermission: 'user:copy'
  }
})

const formConfig = reactive({ /* ... */ })
const searchConfig = reactive({ /* ... */ })
</script>

效果:仅有对应权限时,工具栏的「添加」「删除」和操作列的「编辑」「复制」「删除」才会显示;未注入 hasPermission 或未配置权限码时,仅由 showAdd、showEdit 等控制,与未接入权限时行为一致。


六、行为小结 ​

场景行为
未传入全局 hasPermission不做权限校验,仅按 showXxx、formConfig、deleteConfig 等决定是否显示按钮
传入了 hasPermission 但未配置某按钮的权限码该按钮只按原有 showXxx 等逻辑显示
传入了 hasPermission 且配置了权限码在原有显示条件基础上,再要求 hasPermission(权限码) 为 true,两者都满足才显示
权限码为数组hasPermission 会对数组中每个码调用,有任一为 true 即通过
操作列权限码为函数按行传入 row,用返回的权限码(或数组)调用 hasPermission