Vue.js 3 + Axios异步请求后表格未更新问题求助
问题描述
我排查后确认所有逻辑都已正确实现,但创建新公司后进入概览页面,表格始终无法渲染数据。浏览器控制台能看到restapi-companies输出的所有已创建公司的数据,请求获取公司数据的过程也没有异常。想问下是不是需要触发特定事件,或者问题出在哪里?
相关代码
1. restapi-companies.ts
export type CompanyPojo = { id: number; name: string; legalForm: string; additionalName: string; }; export type CompanyPojoResponse = { data: CompanyPojo[]; }; import axios from "axios"; export async function findAllCompanies() { try { const { data, status } = await axios.get<CompanyPojoResponse>( "http://localhost:9050/api/v1/company/all", { headers: { "Content-Type": "application/json", Authorization: "Basic YWRtaW46YWRtaW5QYXNz", }, } ); console.log(JSON.stringify(data, null, 4)); console.log("response status is: ", status); return data; } catch (error) { if (axios.isAxiosError(error)) { console.log("error message: ", error.message); console.log("error message: ", error); } else { console.log("unexpected error: ", error); } } return <CompanyPojoResponse>{}; }
2. Vue模板代码
<script> import { findAllCompanies } from "@/rest/restapi-companies" import { ref } from "vue" export default { data() { return { companies: ref([]) } }, mounted() { findAllCompanies().then((response) => { this.companies = response.data }) } } </script> <template> <div class="top-nav"> <nav> <RouterLink to="/new-company">New Company</RouterLink> </nav> </div> <table id="companyTable"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Additional Name</th> <th>Legal Form</th> </tr> </thead> <tbody> <tr v-for="company in companies"> <td>{{ company.id }}</td> <td>{{ company.name }}</td> <td>{{ company.additionalName }}</td> <td>{{ company.legalForm }}</td> </tr> </tbody> </table> </template>
问题原因与修复方案
核心问题
你在Vue Options API中错误地使用了Composition API的ref包裹data()里的属性,导致响应式失效。Options API的data返回的对象会被Vue自动处理成响应式,不需要额外用ref包装,这会让companies失去响应式特性,数据更新后无法触发视图渲染。
另外,findAllCompanies的错误分支返回了空对象,若请求出错,response.data会是undefined,可能引发赋值异常。
修复步骤
方案1:修正Options API写法
把data()中的companies: ref([])改为普通数组,去掉ref包裹:
export default { data() { return { companies: [] // 直接用普通数组,Vue会自动处理为响应式 } }, mounted() { findAllCompanies().then((response) => { // 添加空值判断,避免请求出错时赋值undefined this.companies = response?.data || [] }) } }
方案2:改用Composition API(推荐)
如果想使用ref,建议切换到<script setup>语法,这是Vue 3的推荐写法:
<script setup> import { findAllCompanies } from "@/rest/restapi-companies" import { ref, onMounted } from "vue" const companies = ref([]) onMounted(() => { findAllCompanies().then((response) => { companies.value = response?.data || [] }) }) </script> <template> <!-- 模板部分保持不变 --> <div class="top-nav"> <nav> <RouterLink to="/new-company">New Company</RouterLink> </nav> </div> <table id="companyTable"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Additional Name</th> <th>Legal Form</th> </tr> </thead> <tbody> <tr v-for="company in companies"> <td>{{ company.id }}</td> <td>{{ company.name }}</td> <td>{{ company.additionalName }}</td> <td>{{ company.legalForm }}</td> </tr> </tbody> </table> </template>
内容的提问来源于stack exchange,提问作者Tony B
相关产品推荐
相关产品推荐

