Nuxt3中使用Sanity获取数据后无法访问对象属性求助
Nuxt3 + Sanity 数据属性访问问题解决思路
问题概述
在Nuxt3项目中使用Sanity作为CMS时,通过useSanityQuery获取数据后,直接打印data能看到预期的完整数据对象,但尝试访问data.seoTitle这类属性时返回undefined。
相关代码示例
页面组件代码
<script setup lang="ts"> const query = groq`*[_type == "seoContent"]{ seoTitle, seoDescription, }[0]` const { data, refresh } = useSanityQuery(query) console.log(data.seoTitle) // 输出undefined // 注释的SEO设置代码也无法正常工作 // if(data.seoTitle) { // useServerSeoMeta({ // title: data.seoTitle, // ogTitle: data.seoTitle, // description: data.seoDescription, // ogDescription: data.seoDescription, // }) // } </script>
Sanity Schema 定义
export default { name: 'seoContent', type: 'document', title: 'SEO Content', fields: [ { name: 'title', type: 'string', title: 'Document Title' }, { name: 'seoTitle', type: 'string', title: 'SEO Title' }, { name: 'seoDescription', type: 'string', title: 'SEO Description' }, ] }
原因分析
- 响应式包装特性:
useSanityQuery返回的data是Vue响应式Ref对象,直接访问data.seoTitle相当于访问Ref对象本身的属性,而非内部存储的实际数据,正确访问方式应为data.value.seoTitle。 - 异步加载时机:数据获取是异步操作,组件初始化阶段执行
console.log时,data.value可能还未完成数据填充,此时访问属性自然返回undefined。而浏览器控制台会对对象做惰性展开,当手动展开data时数据已加载完成,因此能看到完整内容。
解决方法
方法1:顶层await等待数据加载完成
在<script setup>中支持顶层await,直接等待useSanityQuery完成后再访问属性:
<script setup lang="ts"> const query = groq`*[_type == "seoContent"]{ seoTitle, seoDescription, }[0]` // 用await等待异步数据返回 const { data, refresh } = await useSanityQuery(query) console.log(data.seoTitle) // 正常输出内容 if(data.seoTitle) { useServerSeoMeta({ title: data.seoTitle, ogTitle: data.seoTitle, description: data.seoDescription, ogDescription: data.seoDescription, }) } </script>
方法2:使用监听函数处理数据更新
如果不想用顶层await,可通过watch监听data变化,在数据就绪后执行逻辑:
<script setup lang="ts"> const query = groq`*[_type == "seoContent"]{ seoTitle, seoDescription, }[0]` const { data, refresh } = useSanityQuery(query) // 监听data变化,数据就绪后执行操作 watch(data, (newSeoData) => { if (!newSeoData) return console.log(newSeoData.seoTitle) useServerSeoMeta({ title: newSeoData.seoTitle, ogTitle: newSeoData.seoTitle, description: newSeoData.seoDescription, ogDescription: newSeoData.seoDescription, }) }, { immediate: true }) // 立即执行一次监听逻辑 </script>
方法3:可选链处理未就绪状态
临时调试或处理可选状态时,可结合.value和可选链操作符避免报错:
console.log(data.value?.seoTitle)
内容的提问来源于stack exchange,提问作者samuelreichor
相关产品推荐
相关产品推荐

