Nuxt3中useFetch请求成功但页面不渲染数据的问题问询
Nuxt3中useFetch数据获取成功但页面不渲染的问题排查与解决
核心问题分析
你遇到的问题根源在于对useFetch返回值的响应式处理错误,以及数据过滤逻辑中的多处代码问题:
- useFetch返回的
data是一个ref包装的响应式对象,直接访问courses.length而非courses.value.length,会在数据未加载完成时获取到undefined,中断后续逻辑。 - 将ref直接赋值给reactive对象后,错误的赋值操作导致响应式丢失,模板无法正确遍历数据。
- 循环条件错误(
i <= courses.length)触发数组越界报错,中断数据过滤逻辑。 - watchEffect中的逻辑存在重复赋值和重复添加数据的问题,导致数据结构混乱。
另外,你对SSR的理解是正确的:onMounted仅在客户端执行,若数据处理逻辑放在其中,服务器端渲染时无法生成包含数据的HTML,确实会影响SEO。而useFetch默认会在服务器和客户端均执行,结合computed处理数据可以完整保留SSR优势。
修正方案
通过使用computed进行数据过滤简化逻辑,同时确保响应式和SSR兼容性:
修正后的Script代码
<script setup> import FooterOne from "../Common/FooterOne.vue"; import PageTitle from "../Common/PageTitle.vue"; import Pagination from "../Common/Pagination.vue"; import CourseBar from "./CourseBar.vue"; import Header from "../Common/Header.vue"; import ShopSidebar from "../Common/ShopSidebar.vue"; // 原代码中使用了该组件但未导入 const props = defineProps(['category', 'order']) // 使用useFetch获取数据,自动处理SSR const { data: courses } = await useFetch("/api/courses", { query: { sort: props.order || 'asc' // 简化条件判断 } }) // 使用computed根据category过滤课程,自动响应props和courses的变化 const filteredCourses = computed(() => { if (!courses.value || !props.category) { return courses.value || [] // 处理数据未加载或无category的情况 } // 用filter方法替代手动循环,避免越界问题 return courses.value.filter(el => el.category === props.category) }) </script>
修正后的模板部分
将原模板中的v-for="item in state.courses"替换为:
<div class="col-xl-4 col-lg-6 col-md-6" v-for="item in filteredCourses" :key="item.id">
关键优化点说明
- 用computed替代watchEffect和onMounted:computed会自动追踪依赖(
courses.value和props.category),在服务器端渲染时也能计算出正确的过滤结果,完美保留SEO优势。 - 正确处理ref的取值:通过
courses.value访问ref包装的数组,避免初始阶段的undefined报错。 - 简化逻辑:去掉不必要的reactive和复杂的watch逻辑,代码更易维护且符合Nuxt3的响应式最佳实践。
- 修复数组越界问题:使用
filter方法替代手动循环,彻底避免循环条件错误导致的报错。
内容的提问来源于stack exchange,提问作者defiant
相关产品推荐
相关产品推荐

