Vue组合式API集成TanStack Query与Vee Validate时丢失响应性
解决方案
问题核心在于两点:
- 你直接用
!!currentServiceType判断enabled状态,但传入的是toRef返回的响应式对象时,!!currentServiceType始终为true(因为ref本身是对象,而非其内部value值),导致enabled无法跟随表单值变化。 - useQuery的配置项需要正确追踪响应式依赖,确保
currentServiceType的value变化时,queryKey、enabled等能同步更新。
修改自定义Hook如下:
import { supabase } from '@modules/supabase'; import { useQuery } from '@tanstack/vue-query'; import { MaybeRef, unref, computed } from 'vue'; export function useServicesTitleList( currentServiceType: MaybeRef<string | undefined> ) { // 用computed创建响应式的enabled状态,基于currentServiceType的实际值 const isEnabled = computed(() => !!unref(currentServiceType)); return useQuery({ queryKey: ['servicesTitleList', currentServiceType], // Vue Query会自动追踪queryKey中的ref值变化,无需手动unref initialData: [], enabled: isEnabled, queryFn: async () => { // 在queryFn中必须用unref获取当前的实际值 const serviceType = unref(currentServiceType); if (!serviceType) return []; const { data } = await supabase .from('SomeTable') .select('*') .eq('type0', serviceType); return ( data?.map((d) => ({ label: d.display, value: d.display, })) ?? [] ); }, }); }
组件调用无需修改,保持原样即可:
const { handleSubmit, isSubmitting, values } = useForm({ validationSchema: toTypedSchema(schema), initialValues: {}, }); const { data: titleOpts, isFetching: loadingTitles } = useServicesTitleList( toRef(values, 'type') );
关键说明
unref的作用:统一处理MaybeRef类型(可能是ref或原始值),确保获取到的是实际value值而非ref对象本身。- 响应式enabled:用
computed包裹enabled的判断逻辑,确保currentServiceType的value变化时,enabled状态同步更新,触发useQuery的启用/禁用逻辑。 - queryKey自动追踪:Vue Query在Vue环境下会自动监听queryKey中的ref值变化,当
currentServiceType的value更新时,会自动触发查询重新执行。
内容的提问来源于stack exchange,提问作者ScreamZ
相关产品推荐
相关产品推荐

