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

Vue3中如何正确将异步数据传递给子组件?

解决Vue父组件异步数据传递给子组件的未定义错误

问题说明

父组件在onMounted钩子中异步获取数据后传递给子组件,子组件抛出错误:TypeError: Cannot read properties of undefined (reading 'startDateTime'),核心原因是异步数据加载未完成时,子组件已完成初始化,此时传入的props为undefined,同时父组件还存在异步函数赋值错误的问题。

现有代码

父组件代码

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import TestForm from '../components/TestForm.vue';

const testMe = ref();
// testMe.value = {
//   id: 1,
//   startDateTime: '2023-06-26T09:43:32.203Z',
// };

onMounted(() => {
  // 错误:async函数直接赋值会得到Promise,而非实际数据
  const newObject2 = fetchData();
  console.log('onMounted testing newObject2', newObject2);
  testMe.value = newObject2;
});

async function fetchData() {
  const res = await fetch('http://localhost:4000/testMes');
  const data = await res.json();
  const newObject = data[0];
  console.log('testing the async function data from json:', newObject);
  return newObject;
}
</script>

<template>
  <div>
    <TestForm :testProps="testMe" />
  </div>
</template>

子组件TestForm.vue代码

<script setup lang="ts">
import { ref } from 'vue';

const props = defineProps(['testProps']);

const startDateTime = ref('');

// 错误:初始化时props.testProps为undefined,直接访问startDateTime抛出异常
// eslint-disable-next-line vue/no-setup-props-destructure
startDateTime.value = props.testProps.startDateTime;
</script>

<template>
  <div>
    {{ startDateTime }}
  </div>
</template>

正确实现方案

第一步:修复父组件的异步数据赋值

fetchData是异步函数,直接赋值会将Promise对象传给testMe,需要用await等待异步操作完成,同时把onMounted回调改为async函数:

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import TestForm from '../components/TestForm.vue';

const testMe = ref();

onMounted(async () => {
  // 用await等待异步函数返回实际数据
  const newObject2 = await fetchData();
  console.log('onMounted testing newObject2', newObject2);
  testMe.value = newObject2;
});

async function fetchData() {
  const res = await fetch('http://localhost:4000/testMes');
  const data = await res.json();
  const newObject = data[0];
  console.log('testing the async function data from json:', newObject);
  return newObject;
}
</script>

<template>
  <div>
    <TestForm :testProps="testMe" />
  </div>
</template>

第二步:子组件处理未定义场景

提供三种可选方案,根据实际需求选择:

方案1:使用可选链+监听props变化

通过可选链?.避免undefined报错,同时用watch监听props更新,确保数据同步:

<script setup lang="ts">
import { ref, watch } from 'vue';

const props = defineProps(['testProps']);

const startDateTime = ref('');

// 初始化时用可选链安全访问
startDateTime.value = props.testProps?.startDateTime || '';

// 监听props变化,实时更新本地ref
watch(() => props.testProps, (newVal) => {
  startDateTime.value = newVal?.startDateTime || '';
}, { immediate: true });
</script>

<template>
  <div>
    {{ startDateTime }}
  </div>
</template>

方案2:模板中直接使用可选链

如果不需要将props值存储到本地ref,可直接在模板中处理,简化代码:

<script setup lang="ts">
defineProps(['testProps']);
</script>

<template>
  <div>
    {{ testProps?.startDateTime || '' }}
  </div>
</template>

方案3:父组件中条件渲染子组件

在父组件中,仅当testMe有值时才渲染子组件,确保子组件初始化时props已存在有效数据:

<template>
  <div>
    <TestForm :testProps="testMe" v-if="testMe" />
  </div>
</template>

内容的提问来源于stack exchange,提问作者Samuel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:37:06