Vue3中onBeforeMount数组有值,onMounted中为空的问题求助
问题原因及解决方案
核心问题1:数组未使用响应式声明
你定义的studentList是普通JavaScript数组,不是Vue3的响应式对象。这意味着即使后续往数组里push了数据,Vue无法感知到这个变化,模板也不会更新,所以始终显示NodataFound组件。虽然开发者工具能看到数组内容(数组是引用类型,内容确实被修改了),但模板的依赖追踪没触发更新。
核心问题2:异步请求导致钩子执行顺序问题
onBeforeMount是异步函数,其中的await axios.get()会暂停当前钩子的执行流程。Vue的钩子执行顺序是:
onBeforeMount同步执行到await处,暂停等待请求响应- 组件完成挂载,触发
onMounted钩子(此时请求还没返回,studentList还是空数组,所以打印长度为0) - 后续请求完成,才会执行
push操作往数组里加数据
修复代码
修改studentList的声明,使用Vue3的ref创建响应式数组:
<script setup lang="ts"> import {inject, onBeforeMount, onMounted, ref} from "vue"; import TableList from "@/components/TableList.vue"; import {Student} from "@/types/Student"; import PaginationTable from "@/components/PaginationTable.vue"; import NodataFound from "@/components/NodataFound.vue"; const axios = inject('axios'); const pageNumber = ref(0); const sizeNumber = ref(2); // 改成响应式数组 const studentList = ref<Student[]>([]); const props = defineProps({ japanese: {type: String, required: true}, english: {type: String, required: true}, page: {type: Number, required: false}, }) function pageEmitReceived(page): void { pageNumber.value = page; } onMounted(() => { console.log(studentList.value.length); }) onBeforeMount(async () => { try { const response = await axios.get('/' + props.english + '?page=' + pageNumber.value + '&size=' + sizeNumber.value); response.data.forEach(student => { let newStudent = new Student(student.uuid, student.name, student.email, student.dob); // 操作ref的value属性 studentList.value.push(newStudent); }) } catch (error) { console.log(error) } console.log(studentList.value.length) }) </script>
模板部分可以简化判断逻辑:
<template> <section class="col-12" v-if="studentList.length"> <TableList :student-list="studentList" :page="pageNumber"/> <PaginationTable @pageNumberEmit="pageEmitReceived"/> </section> <section v-else> <NodataFound dede="test"/> </section> </template>
额外说明
如果需要在数据加载完成后执行某些操作,不要依赖onMounted(因为请求是异步的,onMounted执行时数据可能还没到),可以直接在请求完成后的代码块里处理,或者用watch监听studentList的变化:
watch(studentList, (newList) => { if (newList.length > 0) { // 数据加载完成后的操作 } }, {immediate: true})
内容的提问来源于stack exchange,提问作者damou_ 1
相关产品推荐
相关产品推荐

