Archived
t-tabs 用官方 list prop 数据驱动(受控 value + 动态增删语义干净);请求纯手动触发,enabled 门控 + refetch,staleTime Infinity 切 tab 不重发,queryKey ['endpoint', path, skKey] 换 key 即新查询;endpoint-panel 的 sk-key computed 读写 store,切 tab 输入保留。
67 lines
2.4 KiB
TypeScript
67 lines
2.4 KiB
TypeScript
/**
|
||
* TanStack Query 接入:手动触发的 endpoint 请求
|
||
*
|
||
* 语义(设计文档 §3.3 定案):
|
||
* - queryKey = [endpointPath, skKey]——同 tab 换 key 是新查询,不同 tab(不同 key)缓存天然隔离
|
||
* - staleTime: Infinity——调试工具的响应不该自己变,切走再切回不自动重发
|
||
* - 手动触发:sendRequest() 置位 enabled,首次发送后才拉数据;再次点击强制 refetch
|
||
*/
|
||
|
||
import { useQuery, type UseQueryReturnType } from '@tanstack/vue-query';
|
||
import { readonly, ref, type Ref } from 'vue';
|
||
|
||
import { requestGatewayEndpoint, type GatewayResponse } from './gateway-client';
|
||
|
||
/** 手动请求的返回契约 */
|
||
export interface ManualEndpointQuery {
|
||
/** 响应数据(GatewayResponse,含 status/ms/bytes/text/json/networkError) */
|
||
data: Readonly<Ref<GatewayResponse | undefined>>;
|
||
/** 请求进行中 */
|
||
isFetching: Readonly<Ref<boolean>>;
|
||
/** 是否已发送过至少一次(区分「未发送」与「发送中」的空态) */
|
||
hasSent: Readonly<Ref<boolean>>;
|
||
/** 触发请求(key 为空时由调用方负责拦截,本层不校验) */
|
||
sendRequest: () => void;
|
||
}
|
||
|
||
/**
|
||
* 手动触发的 endpoint 查询。
|
||
* endpointPath 与 skKey 均为响应式 Ref:换接口 / 换 key 时 queryKey 随之变化(新缓存槽)。
|
||
*/
|
||
export function useManualEndpointQuery(
|
||
endpointPath: Ref<string>,
|
||
skKey: Ref<string>,
|
||
): ManualEndpointQuery {
|
||
const requestEnabled = ref(false);
|
||
const hasSent = ref(false);
|
||
|
||
const query = useQuery<GatewayResponse>({
|
||
queryKey: ['endpoint', endpointPath, skKey],
|
||
queryFn: () => requestGatewayEndpoint(endpointPath.value, skKey.value),
|
||
enabled: requestEnabled,
|
||
staleTime: Infinity,
|
||
gcTime: Infinity,
|
||
retry: false, // 调试工具要看到真实的失败,不重试
|
||
refetchOnWindowFocus: false,
|
||
refetchOnMount: false,
|
||
refetchOnReconnect: false,
|
||
});
|
||
|
||
function sendRequest(): void {
|
||
hasSent.value = true;
|
||
requestEnabled.value = true;
|
||
// 已有缓存(如换回旧 key)时强制重新请求——「发送」按钮的语义就是真的发一次
|
||
void query.refetch();
|
||
}
|
||
|
||
return {
|
||
data: query.data,
|
||
isFetching: query.isFetching,
|
||
hasSent: readonly(hasSent),
|
||
sendRequest,
|
||
};
|
||
}
|
||
|
||
/** 具名导出便于类型引用(避免调用方直接依赖 tanstack 内部类型) */
|
||
export type { UseQueryReturnType };
|