Skip to content

Vben TableAction

TableAction renders a group of action buttons for table operation columns, inspired by the TableAction component from vben2. Built on shadcn-ui, it supports permission control, popconfirm, tooltips, a "more" dropdown, and dividers, and can be reused inside or outside tables.

If the documentation does not cover the details you need, please refer to the online examples.

Before you start

The component carries no business logic (it does not read the permission store directly); permissions are handled by injecting hasPermission, keeping the core layer decoupled and reusable across frameworks. Inside vxe-table, the recommended approach is to render it via a column slot (slots: { default: 'action' }) on the page, without changing the table's original rendering mechanism. :::

Basic Usage

Pass an array of action items via actions, each with text, onClick, etc. danger marks destructive actions, and divider shows separators between buttons.

Tooltip

Add a tooltip to an action via tooltip, accepting a string or a { content, side } object.

PopConfirm

Use popConfirm to require confirmation before the action runs, commonly used for destructive actions like delete.

More Dropdown

Use dropdownActions to collapse secondary actions into a "more" dropdown. moreText customizes the button label.

Permission Control

Set an auth code on an action and inject a hasPermission resolver; actions without permission are hidden.

Usage with vxe-table

Without changing vxe-table's rendering mechanism, declare a slot in the column config and render it on the page.

Recommended: use the adapter-wrapped version The project's #/adapter/vxe-table re-wraps VbenTableAction and injects hasPermission internally (based on useAccess().hasAccessByCodes). So when you import it from the adapter, you no longer need to pass :has-permission — just declare permission codes via the auth field of each action. :::

ts
// data.ts — declare a slot in the column config
{
  align: 'center',
  field: 'operation',
  fixed: 'right',
  slots: { default: 'action' },
  title: $t('system.user.operation'),
  width: 180,
}
vue
<!-- list.vue — import from the adapter; permission is auto-injected, no has-permission needed -->
<script setup lang="ts">
import { VbenTableAction } from '#/adapter/vxe-table';
</script>

<template>
  <Grid>
    <template #action="{ row }">
      <template #action="{ row }">
        <VbenTableAction
          :actions="[
            {
              text: $t('common.detail'),
              icon: 'lucide:eye',
              onClick: () => onDetail(row),
            },
            {
              text: $t('common.edit'),
              icon: 'lucide:edit',
              onClick: () => onEdit(row),
            },
          ]"
          :dropdown-actions="[
            {
              text: $t('common.delete'),
              icon: 'lucide:trash-2',
              danger: true,
              onClick: () => onDelete(row),
              auth: ['AC_100100'],
            },
          ]"
          align="center"
        />
      </template>
    </template>
  </Grid>
</template>

If you import the core component directly from @vben/common-ui (without going through the adapter), the component carries no business logic and you need to inject hasPermission yourself:

vue
<script setup lang="ts">
import { useAccess } from '@vben/access';
import { VbenTableAction } from '@vben/common-ui';

const { hasAccessByCodes } = useAccess();
function hasPermission(auth?: string | string[]) {
  if (!auth) return true;
  return hasAccessByCodes(Array.isArray(auth) ? auth : [auth]);
}
</script>

<template>
  <VbenTableAction
    v-bind="useActions(row, onActionClick)"
    :has-permission="hasPermission"
    align="center"
  />
</template>

API

TableAction Props

PropDescriptionTypeDefault
actionsMain action buttonsActionItem[][]
dropdownActionsActions inside the "more" dropdownActionItem[][]
alignAlignment'start' | 'center' | 'end''end'
dividerWhether to show separators between buttonsbooleanfalse
moreTextLabel for the "more" button (shown beside the icon)string-
hasPermissionPermission resolver; returning false hides the action with that auth (auto-injected when imported from #/adapter/vxe-table, no need to pass manually)(auth?: string | string[]) => boolean-
classCustom class for the root nodestring-

ActionItem

PropDescriptionTypeDefault
textButton textstring-
iconIcon componentstring | VbenIcon-
onClickClick callback() => void-
authPermission code, filtered by hasPermissionstring | string[]-
ifShowWhether to showboolean | (() => boolean)true
disabledWhether disabledbooleanfalse
loadingLoading statebooleanfalse
dangerDestructive action (red text)booleanfalse
tooltipTooltipstring | { content: string; side?: 'top' | 'bottom' | 'left' | 'right' }-
popConfirmPopConfirmTableActionPopConfirm-
variantButton variantButtonVariants['variant']'link'
sizeButton sizeButtonVariants['size']'sm'
keyUnique keystring | number-

TableActionPopConfirm

PropDescriptionTypeDefault
titleConfirm titlestring'Are you sure?'
okTextConfirm button textstring'OK'
cancelTextCancel button textstring'Cancel'
confirmConfirm callback; falls back to action.onClick if omitted() => void-

Contributors

Changelog

Released under the MIT License.