vben
2021-05-30 b1cb86350253dc5be095466966d9469775f4395d
src/components/Table/src/components/TableAction.vue
@@ -1,15 +1,23 @@
<template>
  <div :class="[prefixCls, getAlign]">
    <template v-for="(action, index) in getActions" :key="`${index}`">
    <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 }}
      </PopConfirmButton>
      <Divider type="vertical" v-if="divider && index < getActions.length" />
      <Divider
        type="vertical"
        class="action-divider"
        v-if="divider && index < getActions.length - (dropDownActions ? 0 : 1)"
      />
    </template>
    <Dropdown :trigger="['hover']" :dropMenuList="getDropList">
      <slot name="more" />
    <Dropdown
      :trigger="['hover']"
      :dropMenuList="getDropdownList"
      popconfirm
      v-if="dropDownActions"
    >
      <slot name="more"></slot>
      <a-button type="link" size="small" v-if="!$slots.more">
        <MoreOutlined class="icon-more" />
      </a-button>
@@ -17,17 +25,23 @@
  </div>
</template>
<script lang="ts">
  import { defineComponent, PropType, computed } from 'vue';
  import Icon from '/@/components/Icon/index';
  import { ActionItem } from '/@/components/Table';
  import { PopConfirmButton } from '/@/components/Button';
  import { Divider } from 'ant-design-vue';
  import { Dropdown } from '/@/components/Dropdown';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { defineComponent, PropType, computed, toRaw } from 'vue';
  import { MoreOutlined } from '@ant-design/icons-vue';
  import { propTypes } from '/@/utils/propTypes';
  import { Divider } 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 { propTypes } from '/@/utils/propTypes';
  import { ACTION_COLUMN_FLAG } from '../const';
  export default defineComponent({
    name: 'TableAction',
    components: { Icon, PopConfirmButton, Divider, Dropdown, MoreOutlined },
@@ -41,43 +55,74 @@
        default: null,
      },
      divider: propTypes.bool.def(true),
      outside: propTypes.bool,
    },
    setup(props) {
      const { prefixCls } = useDesign('basic-table-action');
      const table = useTableContext();
      let table: Partial<TableActionType> = {};
      if (!props.outside) {
        table = useTableContext();
      }
      const { hasPermission } = usePermission();
      function isIfShow(action: ActionItem): boolean {
        const ifShow = action.ifShow;
        let isIfShow = true;
        if (isBoolean(ifShow)) {
          isIfShow = ifShow;
        }
        if (isFunction(ifShow)) {
          isIfShow = ifShow(action);
        }
        return isIfShow;
      }
      const getActions = computed(() => {
        return props.actions.map((action) => {
          const { popConfirm } = action;
          return {
            ...action,
            ...(popConfirm || {}),
            onConfirm: popConfirm?.confirm,
            onCancel: popConfirm?.cancel,
            enable: !!popConfirm,
            type: 'link',
            size: 'small',
          };
        });
        return (toRaw(props.actions) || [])
          .filter((action) => {
            return hasPermission(action.auth) && isIfShow(action);
          })
          .map((action) => {
            const { popConfirm } = action;
            return {
              type: 'link',
              size: 'small',
              ...action,
              ...(popConfirm || {}),
              onConfirm: popConfirm?.confirm,
              onCancel: popConfirm?.cancel,
              enable: !!popConfirm,
            };
          });
      });
      const getDropList = computed(() => {
        return props.dropDownActions.map((action, index) => {
          const { label } = action;
          return {
            ...action,
            text: label,
            divider: index < props.dropDownActions.length - 1 ? props.divider : false,
          };
        });
      const getDropdownList = computed(() => {
        return (toRaw(props.dropDownActions) || [])
          .filter((action) => {
            return hasPermission(action.auth) && isIfShow(action);
          })
          .map((action, index) => {
            const { label, popConfirm } = action;
            return {
              ...action,
              ...popConfirm,
              onConfirm: popConfirm?.confirm,
              onCancel: popConfirm?.cancel,
              text: label,
              divider: index < props.dropDownActions.length - 1 ? props.divider : false,
            };
          });
      });
      const getAlign = computed(() => {
        const columns = table.getColumns();
        const columns = (table as TableActionType)?.getColumns?.() || [];
        const actionColumn = columns.find((item) => item.flag === ACTION_COLUMN_FLAG);
        return actionColumn?.align ?? 'left';
      });
      return { prefixCls, getActions, getDropList, getAlign };
      return { prefixCls, getActions, getDropdownList, getAlign };
    },
  });
</script>
@@ -88,6 +133,10 @@
    display: flex;
    align-items: center;
    .action-divider {
      display: table;
    }
    &.left {
      justify-content: flex-start;
    }