Vue中Axios GET请求返回空或Promise,表格渲染异常如何解决
问题解决指南
根因说明
- Vue 模板的插值语法仅支持同步返回的普通值,无法自动解析异步方法返回的 Promise 对象
- 你在方法内打印能看到正确值,是浏览器控制台自动解析了 Promise 的完成结果,但方法实际返回的仍然是 Promise 实例,模板无法直接识别渲染
- 你当前在模板中每行渲染都单独发起接口请求,不仅性能极低,还会因为异步返回时机和 Vue 响应式更新逻辑不匹配,导致返回值无法触发视图更新
推荐解决方案(最优)
提前批量合并数据后再渲染,不要在模板中调用异步方法:
- 在获取
timeSheetListPageable的接口请求成功后,先收集所有去重后的projectId,查询到对应项目名称后提前挂载到每条工时数据上 - 模板直接读取提前挂载好的同步属性即可
示例代码
JS 逻辑修改
// 假设你原获取工时列表的方法为 fetchTimeSheetList async fetchTimeSheetList() { // 1. 先获取工时列表数据 const timeSheetRes = await axios.get('/你的工时列表接口地址') this.timeSheetListPageable = timeSheetRes.data.list // 2. 收集所有去重的项目ID const projectIds = [...new Set(this.timeSheetListPageable.map(item => item.projectId))] // 3. 查询所有项目名称,存入映射表 const projectNameMap = {} for (const id of projectIds) { try { const projectRes = await axios.get(`/project/${id}`) projectNameMap[id] = projectRes.data.name } catch (err) { projectNameMap[id] = '-' console.log(err) } } // 4. 把项目名称合并到每条工时数据中 this.timeSheetListPageable = this.timeSheetListPageable.map(item => ({ ...item, projectName: projectNameMap[item.projectId] })) }
模板修改
<tbody> <tr v-for="(timeSheet,index) in timeSheetListPageable" :key="index"> <td>{{timeSheet.projectName}}</td> </tr> </tbody>
原有写法无效的原因
- 异步方法
getProjectByIds返回的始终是 Promise 对象,即便你在getProjectById中加了await,加了async的方法本身返回值还是 Promise - 模板不会等待 Promise 状态变为完成再渲染,会直接把 Promise 转成字符串输出,就会出现
[object Promise]的结果 - 不要在模板插值中调用会发起请求的方法,每次视图重渲染都会重新触发请求,会产生大量无效请求,严重影响性能
内容的提问来源于stack exchange,提问作者NewProgrammer
相关产品推荐
相关产品推荐

