ApiTransfer.vue 4.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<template>
  <Transfer
    :data-source="getdataSource"
    :filter-option="filterOption"
    :render="(item) => item.title"
    :showSelectAll="showSelectAll"
    :selectedKeys="selectedKeys"
    :targetKeys="getTargetKeys"
    :showSearch="showSearch"
    @change="handleChange"
  />
</template>

<script lang="ts">
V
vben 已提交
15
  import { computed, defineComponent, watch, ref, unref, watchEffect, PropType } from 'vue';
16 17 18 19 20 21 22 23 24 25
  import { Transfer } from 'ant-design-vue';
  import { isFunction } from '/@/utils/is';
  import { get, omit } from 'lodash-es';
  import { propTypes } from '/@/utils/propTypes';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { TransferDirection, TransferItem } from 'ant-design-vue/lib/transfer';
  export default defineComponent({
    name: 'ApiTransfer',
    components: { Transfer },
    props: {
26
      value: { type: Array as PropType<Array<string>> },
27
      api: {
V
vben 已提交
28
        type: Function as PropType<(arg) => Promise<TransferItem[]>>,
29 30 31
        default: null,
      },
      params: { type: Object },
32
      dataSource: { type: Array as PropType<Array<TransferItem>> },
33 34
      immediate: propTypes.bool.def(true),
      alwaysLoad: propTypes.bool.def(false),
V
vben 已提交
35
      afterFetch: { type: Function },
36 37 38 39 40 41 42 43
      resultField: propTypes.string.def(''),
      labelField: propTypes.string.def('title'),
      valueField: propTypes.string.def('key'),
      showSearch: { type: Boolean, default: false },
      disabled: { type: Boolean, default: false },
      filterOption: {
        type: Function as PropType<(inputValue: string, item: TransferItem) => boolean>,
      },
44
      selectedKeys: { type: Array as PropType<Array<string>> },
45
      showSelectAll: { type: Boolean, default: false },
46
      targetKeys: { type: Array as PropType<Array<string>> },
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
    },
    emits: ['options-change', 'change'],
    setup(props, { attrs, emit }) {
      const _dataSource = ref<TransferItem[]>([]);
      const _targetKeys = ref<string[]>([]);
      const { t } = useI18n();

      const getAttrs = computed(() => {
        return {
          ...(!props.api ? { dataSource: unref(_dataSource) } : {}),
          ...attrs,
        };
      });
      const getdataSource = computed(() => {
        const { labelField, valueField } = props;

V
vben 已提交
63
        return unref(_dataSource).reduce((prev, next) => {
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
          if (next) {
            prev.push({
              ...omit(next, [labelField, valueField]),
              title: next[labelField],
              key: next[valueField],
            });
          }
          return prev;
        }, [] as TransferItem[]);
      });
      const getTargetKeys = computed<string[]>(() => {
        if (unref(_targetKeys).length > 0) {
          return unref(_targetKeys);
        }
        if (Array.isArray(props.value)) {
          return props.value;
        }
V
vben 已提交
81
        if (Array.isArray(props.targetKeys)) {
82 83
          return props.targetKeys;
        }
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
        return [];
      });

      function handleChange(keys: string[], direction: TransferDirection, moveKeys: string[]) {
        _targetKeys.value = keys;
        console.log(direction);
        console.log(moveKeys);
        emit('change', keys);
      }

      watchEffect(() => {
        props.immediate && !props.alwaysLoad && fetch();
      });

      watch(
        () => props.params,
        () => {
          fetch();
        },
        { deep: true },
      );

      async function fetch() {
        const api = props.api;
        if (!api || !isFunction(api)) {
          if (Array.isArray(props.dataSource)) {
            _dataSource.value = props.dataSource;
          }
          return;
        }
        _dataSource.value = [];
        try {
          const res = await api(props.params);
          if (Array.isArray(res)) {
            _dataSource.value = res;
            emitChange();
            return;
          }
          if (props.resultField) {
            _dataSource.value = get(res, props.resultField) || [];
          }
          emitChange();
        } catch (error) {
          console.warn(error);
        }
      }
      function emitChange() {
        emit('options-change', unref(getdataSource));
      }
      return { getTargetKeys, getdataSource, t, getAttrs, handleChange };
    },
  });
</script>