Vue3父组件传props至子组件显示undefined问题求助
问题描述
在Vue3项目中,父组件通过嵌套axios异步请求获取数据,数据本身正确,但传递给子组件后,子组件内props.user可正常打印,props.user.name却显示undefined。经排查推测,子组件在异步请求完成前已完成渲染。
父组件代码
<template> <User_Menu v-if="user_info" :user="user_info" :user_tickets="user_tickets"/> </template> <script setup lang="ts"> import User_Menu from "@/components/User/User_Menu.vue" import { useRoute } from 'vue-router' import { ref, reactive, onMounted } from 'vue' import { UserQrInstance } from '@/interfaces/user'; import { UserTickets } from '../interfaces/tickets'; import { post_call, get_call} from "@/api" import { error_notification } from "@/error_notifications" const route = useRoute() const user_id = ref(0) const user_info = reactive({} as UserQrInstance) const user_tickets = reactive([] as UserTickets) const get_user_tickets = async (qr: string) => { try { const response = await post_call('tickets/get_tickets', {qr_code: qr}) Object.assign(user_tickets, response.data) } catch (e){ error_notification(e) } } const get_user = async () => { try { const response = await get_call(`users/find_user/${user_id.value}`) Object.assign(user_info, response.data) await get_user_tickets(response.data.qr_code) } catch (e){ error_notification(e) } } onMounted(() => { user_id.value = route.params.id get_user() }) </script>
子组件代码
<template> {{props.user}} </template> <script setup lang="ts"> const props = defineProps<{user: Ref<UserQrInstance>, user_tickets: Ref<UserTickets>}>() console.log(props.user) // 正常输出 console.log(props.user.name) // 显示undefined </script>
解决方案
不需要额外添加延迟处理,从以下几个方向调整即可解决问题:
修正子组件Props类型定义
父组件传递的user_info是reactive创建的普通对象,并非Ref类型,子组件里错误地将Props类型定义为Ref<UserQrInstance>,导致属性访问异常。修改为:const props = defineProps<{user: UserQrInstance, user_tickets: UserTickets}>()优化父组件渲染判断逻辑
当前父组件用v-if="user_info"判断,但reactive({})本身是一个空对象,判断会直接为真,导致子组件提前渲染。应该改成判断用户数据是否已实际加载,比如根据id或name等必填属性判断:<User_Menu v-if="user_info.id" :user="user_info" :user_tickets="user_tickets"/>子组件中使用安全访问方式
如果需要在子组件模板中直接访问属性,为避免渲染时的undefined报错,可使用可选链操作符:<template> {{ props.user?.name }} </template>或者在子组件内部用
v-if做条件渲染:<template> <span v-if="props.user.name">{{ props.user.name }}</span> </template>监听Props变化(可选)
如果需要在子组件脚本中处理异步更新后的Props数据,可通过watch监听:import { watch } from 'vue' watch(() => props.user, (newUser) => { if (newUser.name) { console.log(newUser.name) // 数据更新后执行逻辑 } }, { deep: true })
内容的提问来源于stack exchange,提问作者mathz
相关产品推荐
相关产品推荐

