fix: improve request logic in api-component

* 修复某些情况下updateParam设置的参数可能不会提交给api的问题
* 修复在上一个请求尚未完成前如果params发生了变更,将不会再触发新的api请求
---------

Co-authored-by: Netfan <netfan@foxmail.com>
pull/152/head
lghuahua 2025-06-20 08:42:45 +08:00 committed by GitHub
parent 97b8e28a2b
commit 986eacae9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 25 additions and 8 deletions

View File

@ -3,11 +3,11 @@ import type { Component } from 'vue';
import type { AnyPromiseFunction } from '@vben/types';
import { computed, ref, unref, useAttrs, watch } from 'vue';
import { computed, nextTick, ref, unref, useAttrs, watch } from 'vue';
import { LoaderCircle } from '@vben/icons';
import { get, isEqual, isFunction } from '@vben-core/shared/utils';
import { cloneDeep, get, isEqual, isFunction } from '@vben-core/shared/utils';
import { objectOmit } from '@vueuse/core';
@ -104,6 +104,8 @@ const refOptions = ref<OptionsItem[]>([]);
const loading = ref(false);
//
const isFirstLoaded = ref(false);
//
const hasPendingRequest = ref(false);
const getOptions = computed(() => {
const { labelField, valueField, childrenField, numberToString } = props;
@ -146,18 +148,26 @@ const bindProps = computed(() => {
});
async function fetchApi() {
let { api, beforeFetch, afterFetch, params, resultField } = props;
const { api, beforeFetch, afterFetch, resultField } = props;
if (!api || !isFunction(api) || loading.value) {
if (!api || !isFunction(api)) {
return;
}
//
if (loading.value) {
hasPendingRequest.value = true;
return;
}
refOptions.value = [];
try {
loading.value = true;
let finalParams = unref(mergedParams);
if (beforeFetch && isFunction(beforeFetch)) {
params = (await beforeFetch(params)) || params;
finalParams = (await beforeFetch(cloneDeep(finalParams))) || finalParams;
}
let res = await api(params);
let res = await api(finalParams);
if (afterFetch && isFunction(afterFetch)) {
res = (await afterFetch(res)) || res;
}
@ -177,6 +187,13 @@ async function fetchApi() {
isFirstLoaded.value = false;
} finally {
loading.value = false;
//
if (hasPendingRequest.value) {
hasPendingRequest.value = false;
// 使 nextTick
await nextTick();
fetchApi();
}
}
}
@ -190,7 +207,7 @@ async function handleFetchForVisible(visible: boolean) {
}
}
const params = computed(() => {
const mergedParams = computed(() => {
return {
...props.params,
...unref(innerParams),
@ -198,7 +215,7 @@ const params = computed(() => {
});
watch(
params,
mergedParams,
(value, oldValue) => {
if (isEqual(value, oldValue)) {
return;