You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:20:37