vben
2021-08-24 56a966cfbf8db5b29a42185f0f25a0e800c30dbb
提交 | 用户 | age
59eb82 1 <template>
2   <a-tree-select v-bind="getAttrs" @change="handleChange">
3     <template #[item]="data" v-for="item in Object.keys($slots)">
b1f317 4       <slot :name="item" v-bind="data || {}"></slot>
59eb82 5     </template>
6     <template #suffixIcon v-if="loading">
7       <LoadingOutlined spin />
8     </template>
9   </a-tree-select>
10 </template>
11
12 <script lang="ts">
13   import { computed, defineComponent, watch, ref, onMounted, unref } from 'vue';
14   import { TreeSelect } from 'ant-design-vue';
15   import { isArray, isFunction } from '/@/utils/is';
16   import { get } from 'lodash-es';
17   import { propTypes } from '/@/utils/propTypes';
18   import { LoadingOutlined } from '@ant-design/icons-vue';
19   export default defineComponent({
20     name: 'ApiTreeSelect',
21     components: { ATreeSelect: TreeSelect, LoadingOutlined },
22     props: {
23       api: { type: Function as PropType<(arg?: Recordable) => Promise<Recordable>> },
24       params: { type: Object },
25       immediate: { type: Boolean, default: true },
26       resultField: propTypes.string.def(''),
27     },
28     emits: ['options-change', 'change'],
29     setup(props, { attrs, emit }) {
30       const treeData = ref<Recordable[]>([]);
31       const isFirstLoaded = ref<Boolean>(false);
32       const loading = ref(false);
33       const getAttrs = computed(() => {
34         return {
35           ...(props.api ? { treeData: unref(treeData) } : {}),
36           ...attrs,
37         };
38       });
39
40       function handleChange(...args) {
41         emit('change', ...args);
42       }
43
44       watch(
45         () => props.params,
46         () => {
47           isFirstLoaded.value && fetch();
c734f6 48         },
56a966 49         { deep: true },
59eb82 50       );
51
52       watch(
53         () => props.immediate,
54         (v) => {
55           v && !isFirstLoaded.value && fetch();
56a966 56         },
59eb82 57       );
58
59       onMounted(() => {
60         props.immediate && fetch();
61       });
62
63       async function fetch() {
64         const { api } = props;
65         if (!api || !isFunction(api)) return;
66         loading.value = true;
67         treeData.value = [];
68         let result;
69         try {
70           result = await api(props.params);
71         } catch (e) {
72           console.error(e);
73         }
74         loading.value = false;
75         if (!result) return;
76         if (!isArray(result)) {
77           result = get(result, props.resultField);
78         }
79         treeData.value = (result as Recordable[]) || [];
80         isFirstLoaded.value = true;
81         emit('options-change', treeData.value);
82       }
83       return { getAttrs, loading, handleChange };
84     },
85   });
86 </script>