vben
2021-08-24 56a966cfbf8db5b29a42185f0f25a0e800c30dbb
src/components/Table/src/components/TableAction.vue
@@ -1,20 +1,31 @@
<template>
  <div :class="[prefixCls, getAlign]">
  <div :class="[prefixCls, getAlign]" @click="onCellClick">
    <template v-for="(action, index) in getActions" :key="`${index}-${action.label}`">
      <PopConfirmButton v-bind="action">
        <Icon :icon="action.icon" class="mr-1" v-if="action.icon" />
        {{ action.label }}
      <Tooltip v-if="action.tooltip" v-bind="getTooltip(action.tooltip)">
        <PopConfirmButton v-bind="action">
          <Icon :icon="action.icon" :class="{ 'mr-1': !!action.label }" v-if="action.icon" />
          <template v-if="action.label">{{ action.label }}</template>
        </PopConfirmButton>
      </Tooltip>
      <PopConfirmButton v-else v-bind="action">
        <Icon :icon="action.icon" :class="{ 'mr-1': !!action.label }" v-if="action.icon" />
        <template v-if="action.label">{{ action.label }}</template>
      </PopConfirmButton>
      <Divider
        type="vertical"
        v-if="divider && index < getActions.length - (dropDownActions ? 0 : 1)"
        class="action-divider"
        v-if="
          divider &&
          index < getActions.length - (dropDownActions ? 0 : 1) &&
          getDropdownList.length > 0
        "
      />
    </template>
    <Dropdown
      :trigger="['hover']"
      :dropMenuList="getDropdownList"
      popconfirm
      v-if="dropDownActions"
      v-if="dropDownActions && getDropdownList.length > 0"
    >
      <slot name="more"></slot>
      <a-button type="link" size="small" v-if="!$slots.more">
@@ -24,26 +35,23 @@
  </div>
</template>
<script lang="ts">
  import { defineComponent, PropType, computed, toRaw } from 'vue';
  import { defineComponent, PropType, computed, toRaw, unref } from 'vue';
  import { MoreOutlined } from '@ant-design/icons-vue';
  import { Divider } from 'ant-design-vue';
  import { Divider, Tooltip, TooltipProps } from 'ant-design-vue';
  import Icon from '/@/components/Icon/index';
  import { ActionItem, TableActionType } from '/@/components/Table';
  import { PopConfirmButton } from '/@/components/Button';
  import { Dropdown } from '/@/components/Dropdown';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { useTableContext } from '../hooks/useTableContext';
  import { usePermission } from '/@/hooks/web/usePermission';
  import { isBoolean, isFunction } from '/@/utils/is';
  import { isBoolean, isFunction, isString } from '/@/utils/is';
  import { propTypes } from '/@/utils/propTypes';
  import { ACTION_COLUMN_FLAG } from '../const';
  export default defineComponent({
    name: 'TableAction',
    components: { Icon, PopConfirmButton, Divider, Dropdown, MoreOutlined },
    components: { Icon, PopConfirmButton, Divider, Dropdown, MoreOutlined, Tooltip },
    props: {
      actions: {
        type: Array as PropType<ActionItem[]>,
@@ -55,6 +63,7 @@
      },
      divider: propTypes.bool.def(true),
      outside: propTypes.bool,
      stopButtonPropagation: propTypes.bool.def(false),
    },
    setup(props) {
      const { prefixCls } = useDesign('basic-table-action');
@@ -86,6 +95,7 @@
          .map((action) => {
            const { popConfirm } = action;
            return {
              getPopupContainer: () => unref((table as any)?.wrapRef.value) ?? document.body,
              type: 'link',
              size: 'small',
              ...action,
@@ -97,7 +107,7 @@
          });
      });
      const getDropdownList = computed(() => {
      const getDropdownList = computed((): any[] => {
        return (toRaw(props.dropDownActions) || [])
          .filter((action) => {
            return hasPermission(action.auth) && isIfShow(action);
@@ -121,7 +131,24 @@
        return actionColumn?.align ?? 'left';
      });
      return { prefixCls, getActions, getDropdownList, getAlign };
      function getTooltip(data: string | TooltipProps): TooltipProps {
        return {
          getPopupContainer: () => unref((table as any)?.wrapRef.value) ?? document.body,
          placement: 'bottom',
          ...(isString(data) ? { title: data } : data),
        };
      }
      function onCellClick(e: MouseEvent) {
        if (!props.stopButtonPropagation) return;
        const path = e.composedPath() as HTMLElement[];
        const isInButton = path.find((ele) => {
          return ele.tagName?.toUpperCase() === 'BUTTON';
        });
        isInButton && e.stopPropagation();
      }
      return { prefixCls, getActions, getDropdownList, getAlign, onCellClick, getTooltip };
    },
  });
</script>
@@ -131,6 +158,10 @@
  .@{prefix-cls} {
    display: flex;
    align-items: center;
    .action-divider {
      display: table;
    }
    &.left {
      justify-content: flex-start;
@@ -153,6 +184,12 @@
      }
    }
    button.ant-btn-circle {
      span {
        margin: auto !important;
      }
    }
    .ant-divider,
    .ant-divider-vertical {
      margin: 0 2px;