Archived
feat(ui): UI 骨架与请求集成(sider、tabs、接口面板 sk-key 走 store、手动查询)
t-tabs 用官方 list prop 数据驱动(受控 value + 动态增删语义干净);请求纯手动触发,enabled 门控 + refetch,staleTime Infinity 切 tab 不重发,queryKey ['endpoint', path, skKey] 换 key 即新查询;endpoint-panel 的 sk-key computed 读写 store,切 tab 输入保留。
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* 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 };
|
||||
Reference in New Issue
Block a user