Nuxt TypeScript中无法访问Sanity查询返回的RefImpl字段问题
问题解决与优化方案
一、Ref.value返回null的原因
你遇到的问题是Vue响应式Ref的控制台特性导致的:
console.dir会实时读取Ref的当前值,因此能显示正确的内部数据;console.log(sizePickerData.value)执行时,可能在该瞬间Ref的value还未完成赋值(即便用了await,部分Nuxt/Sanity组合式函数的异步处理逻辑仍可能存在延迟),或是浏览器控制台的快照机制导致显示为null。
验证与解决:可以用watch监听Ref的变化来确保获取到正确值:
watch(sizePickerData, (newVal) => { console.log(newVal); // 此处能拿到正确数据 }, { immediate: true });
另外注意:部分版本的@nuxtjs/sanity中,useSanityQuery无需手动await,它会自动处理异步数据加载,返回的data是响应式Ref,会在数据就绪后自动更新。
二、Sanity查询的优化实现
1. 用参数化查询替代模板拼接
直接拼接props.data?._ref存在GROQ注入风险,参数化查询更安全、可读性更强:
const sizePickerQuery = groq`*[_id == $ref]`; const { data: sizePickerData } = useSanityQuery<SanityDocument[]>(sizePickerQuery, { params: { ref: props.data?._ref } });
2. 直接获取单个文档(避免数组处理)
根据_id查询的结果只会有一个文档,直接取数组首个元素,简化后续逻辑:
const sizePickerQuery = groq`*[_id == $ref][0]`; const { data: sizePickerData } = useSanityQuery<SanityDocument | null>(sizePickerQuery, { params: { ref: props.data?._ref } });
3. 结合Nuxt的useAsyncData灵活处理
如果需要更精细化控制数据获取逻辑,可搭配useAsyncData与Sanity客户端:
const sanityClient = useSanityClient(); const { data: sizePickerData } = await useAsyncData('size-picker', async () => { if (!props.data?._ref) return null; return sanityClient.fetch<SanityDocument>(groq`*[_id == $ref][0]`, { ref: props.data._ref }); });
内容的提问来源于stack exchange,提问作者Ola Hagen Bendixen
相关产品推荐
相关产品推荐

