VueUse useVirtualList初始化报错:类型‘AppItem[] | undefined’不兼容
问题原因
TanStack Query 的 useQuery 返回的 data 字段初始状态是 undefined——因为查询还未完成时没有数据返回。你直接将 apps.value 传给 useVirtualList,此时 apps.value 的类型是 AppItem[] | undefined,但 useVirtualList 的第一个参数要求是 MaybeRef<AppItem[]>,不允许传入 undefined,因此触发 TypeScript 类型错误。
解决方案
以下是几种可行的修复方式:
方法一:确保 apps 始终为数组类型(推荐)
在 useApps 钩子中,给 useQuery 的 data 字段设置默认空数组,或者通过 initialData 配置初始化:
const useApps = () => { const params = reactive({ appName: "", state: "", bucket: "", }); const { isLoading, data: apps = [], // 解构时直接给默认值 error, } = useQuery(["apps"], () => getApps(params)); // 或者用 initialData 配置: // const { isLoading, data: apps, error } = useQuery(["apps"], () => getApps(params), { // initialData: [], // }); return { isLoading, apps, error, params }; };
这样 apps 的类型会被推断为 AppItem[],不再包含 undefined,直接传给 useVirtualList 就不会报错。
方法二:传参时兜底空数组
在调用 useVirtualList 时,使用空数组兜底 apps.value 的 undefined 情况:
const { apps, isLoading, error } = useApps(); const { list, containerProps, wrapperProps } = useVirtualList(apps.value ?? [], { itemHeight: 22, });
这种方式不需要修改 useApps 钩子,适合快速修复。
方法三:延迟初始化虚拟列表
如果需要等数据加载完成后再初始化虚拟列表,可以结合 watch 和 isLoading 状态:
const { apps, isLoading, error } = useApps(); // 先初始化默认值 const [list, containerProps, wrapperProps] = [ ref([]), ref({}), ref({}) ] as [ Ref<ReturnType<typeof useVirtualList>['list']>, Ref<ReturnType<typeof useVirtualList>['containerProps']>, Ref<ReturnType<typeof useVirtualList>['wrapperProps']> ]; watch([isLoading, apps], () => { if (!isLoading && apps.value) { const virtualListResult = useVirtualList(apps.value, { itemHeight: 22, }); list.value = virtualListResult.list; containerProps.value = virtualListResult.containerProps; wrapperProps.value = virtualListResult.wrapperProps; } }, { immediate: true });
这种方式适合必须依赖真实数据才能渲染虚拟列表的场景。
内容的提问来源于stack exchange,提问作者FeckNeck
相关产品推荐
相关产品推荐

