From 077b7006de46ad644aa321843303430513126ad0 Mon Sep 17 00:00:00 2001 From: Ben Lin <maobin001@msn.com> Date: 星期二, 18 六月 2024 18:54:17 +0800 Subject: [PATCH] 更新 --- src/components/Form/src/components/ApiTree.vue | 175 +++++++++++++++++++++++++++++++-------------------------- 1 files changed, 95 insertions(+), 80 deletions(-) diff --git a/src/components/Form/src/components/ApiTree.vue b/src/components/Form/src/components/ApiTree.vue index 41a7413..56f9358 100644 --- a/src/components/Form/src/components/ApiTree.vue +++ b/src/components/Form/src/components/ApiTree.vue @@ -1,92 +1,107 @@ <template> - <a-tree v-bind="getAttrs" @change="handleChange"> + <Tree v-bind="getAttrs" v-model:selectedKeys="state"> <template #[item]="data" v-for="item in Object.keys($slots)"> <slot :name="item" v-bind="data || {}"></slot> </template> - <template #suffixIcon v-if="loading"> - <LoadingOutlined spin /> - </template> - </a-tree> + </Tree> </template> -<script lang="ts"> - import { type Recordable, type AnyFunction } from '@vben/types'; - import { type PropType, computed, defineComponent, watch, ref, onMounted, unref } from 'vue'; - import { Tree } from 'ant-design-vue'; - import { isArray, isFunction } from '/@/utils/is'; +<script lang="ts" setup> + import { type Recordable } from '@vben/types'; + import { type PropType, computed, watch, ref, onMounted, unref, useAttrs } from 'vue'; + import { Tree, TreeProps } from 'ant-design-vue'; + import { isFunction } from '@/utils/is'; import { get } from 'lodash-es'; - import { propTypes } from '/@/utils/propTypes'; - import { LoadingOutlined } from '@ant-design/icons-vue'; + import { DataNode } from 'ant-design-vue/es/tree'; + import { useRuleFormItem } from '@/hooks/component/useFormItem'; - export default defineComponent({ - name: 'ApiTree', - components: { ATree: Tree, LoadingOutlined }, - props: { - api: { type: Function as PropType<(arg?: Recordable<any>) => Promise<Recordable<any>>> }, - params: { type: Object }, - immediate: { type: Boolean, default: true }, - resultField: propTypes.string.def(''), - afterFetch: { type: Function as PropType<AnyFunction> }, + defineOptions({ name: 'ApiTree' }); + + const props = defineProps({ + api: { type: Function as PropType<(arg?: any) => Promise<Recordable<any>>> }, + params: { type: Object }, + immediate: { type: Boolean, default: true }, + resultField: { type: String, default: '' }, + beforeFetch: { + type: Function as PropType<Fn>, + default: null, }, - emits: ['options-change', 'change'], - setup(props, { attrs, emit }) { - const treeData = ref<Recordable<any>[]>([]); - const isFirstLoaded = ref<Boolean>(false); - const loading = ref(false); - const getAttrs = computed(() => { - return { - ...(props.api ? { treeData: unref(treeData) } : {}), - ...attrs, - }; - }); - - function handleChange(...args) { - emit('change', ...args); - } - - watch( - () => props.params, - () => { - !unref(isFirstLoaded) && fetch(); - }, - { deep: true }, - ); - - watch( - () => props.immediate, - (v) => { - v && !isFirstLoaded.value && fetch(); - }, - ); - - onMounted(() => { - props.immediate && fetch(); - }); - - async function fetch() { - const { api, afterFetch } = props; - if (!api || !isFunction(api)) return; - loading.value = true; - treeData.value = []; - let result; - try { - result = await api(props.params); - } catch (e) { - console.error(e); - } - if (afterFetch && isFunction(afterFetch)) { - result = afterFetch(result); - } - loading.value = false; - if (!result) return; - if (!isArray(result)) { - result = get(result, props.resultField); - } - treeData.value = (result as Recordable<any>[]) || []; - isFirstLoaded.value = true; - emit('options-change', treeData.value); - } - return { getAttrs, loading, handleChange }; + afterFetch: { + type: Function as PropType<Fn>, + default: null, + }, + value: { + type: Array as PropType<TreeProps['selectedKeys']>, }, }); + + const emit = defineEmits(['options-change', 'change', 'update:value']); + + const attrs = useAttrs(); + + const treeData = ref<DataNode[]>([]); + const isFirstLoaded = ref<Boolean>(false); + const loading = ref(false); + const emitData = ref<any[]>([]); + + const [state] = useRuleFormItem(props, 'value', 'change', emitData); + const getAttrs = computed(() => { + return { + ...(props.api ? { treeData: unref(treeData) } : {}), + ...attrs, + }; + }); + + watch( + () => state.value, + (v) => { + emit('update:value', v); + }, + ); + + watch( + () => props.params, + () => { + !unref(isFirstLoaded) && fetch(); + }, + { deep: true }, + ); + + watch( + () => props.immediate, + (v) => { + v && !isFirstLoaded.value && fetch(); + }, + ); + + onMounted(() => { + props.immediate && fetch(); + }); + + async function fetch() { + let { api, beforeFetch, afterFetch, params, resultField } = props; + if (!api || !isFunction(api)) return; + loading.value = true; + treeData.value = []; + let res; + try { + if (beforeFetch && isFunction(beforeFetch)) { + params = (await beforeFetch(params)) || params; + } + res = await api(params); + if (afterFetch && isFunction(afterFetch)) { + res = (await afterFetch(res)) || res; + } + } catch (e) { + console.error(e); + } + loading.value = false; + if (!res) return; + if (resultField) { + res = get(res, resultField) || []; + } + treeData.value = (res as (Recordable & { key: string | number })[]) || []; + isFirstLoaded.value = true; + emit('options-change', treeData.value); + } </script> -- Gitblit v1.9.3