feat(BasicForm->Components): add beforeFetch & afterFetch to apicomp && perf the code (#3786)

* fix(apitree): fix the error way to use resultfield

* feat: add before & after Fetch fn in apiComp
This commit is contained in:
Electrolux 2024-04-24 18:00:13 +08:00 committed by GitHub
parent 2f655c2127
commit 7ae2ec03a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 134 additions and 49 deletions

View File

@ -69,6 +69,14 @@
displayRenderArray: {
type: Array,
},
beforeFetch: {
type: Function as PropType<Fn>,
default: null,
},
afterFetch: {
type: Function as PropType<Fn>,
default: null,
},
});
const emit = defineEmits(['change', 'defaultChange']);
@ -112,19 +120,25 @@
}, [] as Option[]);
}
async function initialFetch() {
const api = props.api;
async function fetch() {
let { api, beforeFetch, initFetchParams, afterFetch, resultField } = props;
if (!api || !isFunction(api)) return;
apiData.value = [];
loading.value = true;
try {
const res = await api(props.initFetchParams);
if (beforeFetch && isFunction(beforeFetch)) {
initFetchParams = (await beforeFetch(initFetchParams)) || initFetchParams;
}
let res = await api(initFetchParams);
if (afterFetch && isFunction(afterFetch)) {
res = (await afterFetch(res)) || res;
}
if (Array.isArray(res)) {
apiData.value = res;
return;
}
if (props.resultField) {
apiData.value = get(res, props.resultField) || [];
if (resultField) {
apiData.value = get(res, resultField) || [];
}
} catch (error) {
console.warn(error);
@ -136,20 +150,26 @@
const loadData: CascaderProps['loadData'] = async (selectedOptions) => {
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;
const api = props.api;
let { api, beforeFetch, afterFetch, resultField, apiParamKey } = props;
if (!api || !isFunction(api)) return;
try {
const res = await api({
[props.apiParamKey]: Reflect.get(targetOption, 'value'),
});
let param = {
[apiParamKey]: Reflect.get(targetOption, 'value'),
};
if (beforeFetch && isFunction(beforeFetch)) {
param = (await beforeFetch(param)) || param;
}
let res = await api(param);
if (afterFetch && isFunction(afterFetch)) {
res = (await afterFetch(res)) || res;
}
if (Array.isArray(res)) {
const children = generatorOptions(res);
targetOption.children = children;
return;
}
if (props.resultField) {
const children = generatorOptions(get(res, props.resultField) || []);
if (resultField) {
const children = generatorOptions(get(res, resultField) || []);
targetOption.children = children;
}
} catch (e) {
@ -162,7 +182,7 @@
watch(
() => props.immediate,
() => {
props.immediate && initialFetch();
props.immediate && fetch();
},
{
immediate: true,
@ -172,7 +192,7 @@
watch(
() => props.initFetchParams,
() => {
!unref(isFirstLoad) && initialFetch();
!unref(isFirstLoad) && fetch();
},
{ deep: true },
);

View File

@ -57,6 +57,14 @@
labelField: propTypes.string.def('label'),
valueField: propTypes.string.def('value'),
immediate: propTypes.bool.def(true),
beforeFetch: {
type: Function as PropType<Fn>,
default: null,
},
afterFetch: {
type: Function as PropType<Fn>,
default: null,
},
});
const emit = defineEmits(['options-change', 'change', 'update:value']);
@ -95,19 +103,25 @@
);
async function fetch() {
const api = props.api;
let { api, beforeFetch, afterFetch, params, resultField } = props;
if (!api || !isFunction(api)) return;
options.value = [];
try {
loading.value = true;
const res = await api(props.params);
if (beforeFetch && isFunction(beforeFetch)) {
params = (await beforeFetch(params)) || params;
}
let res = await api(params);
if (afterFetch && isFunction(afterFetch)) {
res = (await afterFetch(res)) || res;
}
if (Array.isArray(res)) {
options.value = res;
emitChange();
return;
}
if (props.resultField) {
options.value = get(res, props.resultField) || [];
if (resultField) {
options.value = get(res, resultField) || [];
}
emitChange();
} catch (error) {

View File

@ -54,6 +54,14 @@
type: Array<OptionsItem>,
default: [],
},
beforeFetch: {
type: Function as PropType<Fn>,
default: null,
},
afterFetch: {
type: Function as PropType<Fn>,
default: null,
},
});
const emit = defineEmits(['options-change', 'change', 'update:value']);
@ -103,20 +111,26 @@
);
async function fetch() {
const api = props.api;
let { api, beforeFetch, afterFetch, params, resultField } = props;
if (!api || !isFunction(api) || loading.value) return;
optionsRef.value = [];
try {
loading.value = true;
const res = await api(props.params);
if (beforeFetch && isFunction(beforeFetch)) {
params = (await beforeFetch(params)) || params;
}
let res = await api(params);
if (afterFetch && isFunction(afterFetch)) {
res = (await afterFetch(res)) || res;
}
isFirstLoaded.value = true;
if (Array.isArray(res)) {
optionsRef.value = res;
emitChange();
return;
}
if (props.resultField) {
optionsRef.value = get(res, props.resultField) || [];
if (resultField) {
optionsRef.value = get(res, resultField) || [];
}
emitChange();
} catch (error) {

View File

@ -32,7 +32,14 @@
dataSource: { type: Array as PropType<Array<TransferItem>> },
immediate: propTypes.bool.def(true),
alwaysLoad: propTypes.bool.def(false),
afterFetch: { type: Function },
beforeFetch: {
type: Function as PropType<Fn>,
default: null,
},
afterFetch: {
type: Function as PropType<Fn>,
default: null,
},
resultField: propTypes.string.def(''),
labelField: propTypes.string.def('title'),
valueField: propTypes.string.def('key'),
@ -98,23 +105,29 @@
);
async function fetch() {
const api = props.api;
let { api, beforeFetch, afterFetch, params, resultField, dataSource } = props;
if (!api || !isFunction(api)) {
if (Array.isArray(props.dataSource)) {
_dataSource.value = props.dataSource;
if (Array.isArray(dataSource)) {
_dataSource.value = dataSource;
}
return;
}
_dataSource.value = [];
try {
const res = await api(props.params);
if (beforeFetch && isFunction(beforeFetch)) {
params = (await beforeFetch(params)) || params;
}
let res = await api(params);
if (afterFetch && isFunction(afterFetch)) {
res = (await afterFetch(res)) || res;
}
if (Array.isArray(res)) {
_dataSource.value = res;
emitChange();
return;
}
if (props.resultField) {
_dataSource.value = get(res, props.resultField) || [];
if (resultField) {
_dataSource.value = get(res, resultField) || [];
}
emitChange();
} catch (error) {

View File

@ -7,10 +7,10 @@
</template>
<script lang="ts" setup>
import { type Recordable, type AnyFunction } from '@vben/types';
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 { isArray, isFunction } from '@/utils/is';
import { isFunction } from '@/utils/is';
import { get } from 'lodash-es';
import { DataNode } from 'ant-design-vue/es/tree';
import { useRuleFormItem } from '@/hooks/component/useFormItem';
@ -22,7 +22,14 @@
params: { type: Object },
immediate: { type: Boolean, default: true },
resultField: { type: String, default: '' },
afterFetch: { type: Function as PropType<AnyFunction> },
beforeFetch: {
type: Function as PropType<Fn>,
default: null,
},
afterFetch: {
type: Function as PropType<Fn>,
default: null,
},
value: {
type: Array as PropType<TreeProps['selectedKeys']>,
},
@ -72,25 +79,28 @@
});
async function fetch() {
const { api, afterFetch } = props;
let { api, beforeFetch, afterFetch, params, resultField } = props;
if (!api || !isFunction(api)) return;
loading.value = true;
treeData.value = [];
let result;
let res;
try {
result = await api(props.params);
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);
}
if (afterFetch && isFunction(afterFetch)) {
result = afterFetch(result);
}
loading.value = false;
if (!result) return;
if (!isArray(result)) {
result = get(result, props.resultField);
if (!res) return;
if (resultField) {
res = get(res, resultField) || [];
}
treeData.value = (result as (Recordable & { key: string | number })[]) || [];
treeData.value = (res as (Recordable & { key: string | number })[]) || [];
isFirstLoaded.value = true;
emit('options-change', treeData.value);
}

View File

@ -34,6 +34,14 @@
labelField: propTypes.string.def('title'),
valueField: propTypes.string.def('value'),
childrenField: propTypes.string.def('children'),
beforeFetch: {
type: Function as PropType<Fn>,
default: null,
},
afterFetch: {
type: Function as PropType<Fn>,
default: null,
},
});
const emit = defineEmits(['options-change', 'change', 'load-data']);
@ -88,22 +96,28 @@
}
async function fetch() {
const { api } = props;
let { api, beforeFetch, afterFetch, params, resultField } = props;
if (!api || !isFunction(api) || loading.value) return;
loading.value = true;
treeData.value = [];
let result;
let res;
try {
result = await api(props.params);
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 (!result) return;
if (!isArray(result)) {
result = get(result, props.resultField);
if (!res) return;
if (resultField) {
res = get(res, resultField) || [];
}
treeData.value = (result as Recordable<any>[]) || [];
treeData.value = (res as Recordable<any>[]) || [];
isFirstLoaded.value = true;
emit('options-change', treeData.value);
}