Vue3中onBeforeMount异步请求后子组件onMounted无法获取数据问题
问题原因
你对Vue3生命周期的理解确实存在偏差:onBeforeMount 钩子中的异步操作不会阻塞组件的挂载流程。Vue会继续执行后续的生命周期步骤(包括父组件挂载、子组件挂载),不会等待你的await Task.getTasks()完成。所以当子组件触发onMounted时,父组件的异步请求还处于pending状态,allRequests还是初始的空数组,自然打印为空;而setTimeout延迟1秒后,异步请求大概率已经完成,数据更新后就能拿到正确值。
另外,模板能正常显示是因为Vue的响应式系统会在allRequests更新后自动触发组件重新渲染,模板会同步更新,但onMounted钩子只会执行一次,所以当时的打印结果是空的。
解决方案
不需要用状态管理库,有两种简单的处理方式:
方式一:子组件监听props变化
在子组件中通过watch或watchEffect监听tableData的变化,数据就绪后再执行逻辑:
<script setup> import { watch } from 'vue' const props = defineProps({ tableData: { type: Array, required: true, }, }) // 监听tableData变化,数据更新时执行逻辑 watch(() => props.tableData, (newData) => { if (newData.length) { console.log(newData) // 这里写需要用到数据的业务逻辑 } }, { immediate: true }) // immediate: true 会在组件初始化时立即执行一次检查 </script>
或者用watchEffect自动追踪依赖:
<script setup> import { watchEffect } from 'vue' const props = defineProps({ tableData: { type: Array, required: true, }, }) watchEffect(() => { if (props.tableData.length) { console.log(props.tableData) // 处理逻辑 } }) </script>
方式二:父组件控制子组件渲染时机
在父组件模板中用v-if判断数据是否就绪,只有当allRequests有数据时才渲染子组件,这样子组件挂载时数据已经存在:
<template> <ChildComponent v-if="allRequests.length" :tableData="allRequests" /> </template> <script setup> import { ref, onBeforeMount } from 'vue' import ChildComponent from './ChildComponent.vue' const allRequests = ref([]) onBeforeMount(async () => { allRequests.value = await Task.getTasks() }) </script>
内容的提问来源于stack exchange,提问作者Tifainek
相关产品推荐
相关产品推荐

