Vue3中获取数据传递给子组件的问题及API调用优化咨询
Vue3异步数据传递与API请求优化方案
一、解决子组件undefined错误与数据不更新问题
1. 初始化响应式数据默认值
你的post初始为ref()(即undefined),导致子组件初始化时接收的props为undefined引发错误。给post设置带结构的初始空对象,确保子组件能拿到初始有效值:
<script setup lang="ts"> import { ref } from 'vue' // 初始化带默认结构的空对象 const post = ref({ id: 0, title: '', body: '' }) const load = async () => { const data = await fetch('https://jsonplaceholder.typicode.com/posts/1') post.value = await data.json() } load() </script>
2. 子组件设置Props默认值
在每个子组件中为props定义默认值,即使父组件数据未返回,子组件也不会因undefined报错:
<!-- IdChild.vue --> <template> <p>{{ idP }}</p> </template> <script setup lang="ts"> defineProps({ idP: { type: Number, default: 0 // 设置默认值 } }) </script>
3. 延迟挂载子组件(可选)
用v-if判断数据是否加载完成,确保子组件仅在数据就绪后挂载,彻底避免初始undefined问题:
<template> <h1>Data from Parent</h1> {{ post.id }} - {{ post.title }} - {{ post.body }} <h1>Data from Child</h1> <!-- 仅当post.id存在时渲染子组件 --> <IdChild v-if="post.id" :idP="post.id" /> <TitleChild v-if="post.id" :titleP="post.title" /> <BodyChild v-if="post.id" :bodyP="post.body" /> </template>
子组件不更新排查
确保子组件直接使用props而非重新赋值为ref,因为Vue的props本身是响应式的。如果子组件中写了const id = ref(props.idP),会丢失响应性,应该直接用props.idP。
二、API请求的优化实现方式
1. 结合生命周期钩子发起请求
将请求放在onMounted钩子中,符合组件生命周期逻辑,代码可读性更强:
<script setup lang="ts"> import { ref, onMounted } from 'vue' const post = ref({ id: 0, title: '', body: '' }) const load = async () => { const response = await fetch('https://jsonplaceholder.typicode.com/posts/1') post.value = await response.json() } // 组件挂载后发起请求 onMounted(() => { load() }) </script>
2. 添加错误处理
捕获请求异常,避免页面崩溃,同时可添加错误提示:
<script setup lang="ts"> import { ref, onMounted } from 'vue' const post = ref({ id: 0, title: '', body: '' }) const load = async () => { try { const response = await fetch('https://jsonplaceholder.typicode.com/posts/1') if (!response.ok) throw new Error(`请求失败:${response.status}`) post.value = await response.json() } catch (err) { console.error('数据加载失败:', err) // 可在这里展示错误提示或设置默认数据 } } onMounted(() => { load() }) </script>
3. 使用Suspense实现加载状态(Vue3特性)
通过Suspense组件统一处理异步加载状态,提升用户体验:
<!-- App.vue --> <template> <Suspense> <template #default> <Parent /> </template> <template #fallback> <div>数据加载中...</div> </template> </Suspense> </template>
<!-- Parent.vue --> <script setup lang="ts"> import { ref } from 'vue' const post = ref({ id: 0, title: '', body: '' }) const load = async () => { const response = await fetch('https://jsonplaceholder.typicode.com/posts/1') post.value = await response.json() } // 直接await请求,Suspense会等待Promise完成 await load() </script>
内容的提问来源于stack exchange,提问作者CRK
相关产品推荐
相关产品推荐

