Script Setup顶层await后变量返回Undefined的问题排查与解决
Nuxt3/Vue3中useFetch异步赋值导致变量undefined的问题
问题代码
<script setup> const content = await useFetch('/api/items/published').then((res) => res.data) const items = await content.data.items const issues = await content.data.issues </script> <template> <Gallery :items="items" :layout="layout" @sponsorModalOpen="sponsorModalOpen()" /> </template>
变量items和issues返回undefined,直接通过可选链传递content?.data.items给Gallery组件能正常工作,但无法提前对数据进行处理(如排序)。
问题原因
你错误处理了useFetch的返回值:
- useFetch返回的是一个包含
data(响应式Ref对象)、pending、error等属性的对象 - 通过
.then(res => res.data)拿到的是Ref对象,而非请求返回的原始数据 - Ref对象本身没有
data属性,只有value属性,所以content.data会返回undefined,进而导致items和issues为undefined
解决方案
方案1:监听响应式数据,处理后赋值(推荐,支持响应式更新)
<script setup> // 解构useFetch返回值,data是响应式Ref const { data: content } = await useFetch('/api/items/published') // 初始化响应式变量存储处理后的数据 const items = ref([]) const issues = ref([]) // 监听content变化,请求完成后处理数据 watch(content, (newContent) => { if (newContent?.data) { // 示例:对items进行排序 items.value = [...newContent.data.items].sort((a, b) => a.id - b.id) issues.value = newContent.data.issues } }, { immediate: true }) </script> <template> <Gallery :items="items" :layout="layout" @sponsorModalOpen="sponsorModalOpen()" /> </template>
方案2:直接获取完成后的数据(适合无需响应式更新的场景)
<script setup> // await useFetch会等待请求完成,此时content.value已包含返回数据 const { data: content } = await useFetch('/api/items/published') // 从Ref的value中取出原始数据 const rawData = content.value.data // 处理数据后赋值 const items = ref(rawData.items.sort((a, b) => a.id - b.id)) const issues = ref(rawData.issues) </script> <template> <Gallery :items="items" :layout="layout" @sponsorModalOpen="sponsorModalOpen()" /> </template>
为什么直接传content?.data.items能工作?
在Vue模板中,响应式Ref会自动解包(即自动访问content.value),所以content?.data.items等价于content.value?.data.items。可选链会在请求完成前返回undefined,请求完成后自动获取到正确数据,模板会响应式更新。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

