Vue3 onMounted获取API数据后DOM不渲染,改模板才显示
问题解决:Vue首次加载未渲染API数据,热重载后正常显示
问题根源
你直接用let leagues: League[];声明变量,这不是Vue的响应式变量。当你在onMounted中给它赋值时,Vue无法追踪到这个变化,所以首次加载时DOM不会更新;而修改模板触发热重载时,Vue开发工具会自动处理变量的响应式绑定,因此数据能正常显示。
解决方案
在Vue 3的<script setup>中,必须用ref或reactive创建响应式状态,这样Vue才能监听数据变化并更新DOM。对于数组类型,推荐使用ref:
修改后的AppLeague.vue代码
<template lang=""> <div class="row"> <div class="col-md-12"> <h3>Leagues</h3> </div> <div class="col-md-12"> <ul class="list-group"> <li v-for="(leagueItem, index) in leagues" :key="leagueItem.league_id" class="list-group-item" > {{ index + 1 }}.{{ leagueItem.league_name }} , Status: {{ leagueItem.league_status }}, Code: {{ leagueItem.league_code }} </li> </ul> </div> </div> </template> <script setup lang="ts"> import { onMounted, ref } from "vue"; import customAxios from "@/lib/customAxios"; interface League { league_id: number, league_name: string; league_code: string; league_status: string; } // 用ref创建响应式数组,初始值为空数组 const leagues = ref<League[]>([]); onMounted(async () => { try { const response = await customAxios.get<League[]>(`account/leagues`, { withCredentials: true, }); leagues.value = response.data; // 修改ref的值需要通过.value属性 } catch (error) { console.error("获取联赛数据失败:", error); } }); </script>
额外优化建议
- key值优化:将
:key="index"替换为:key="leagueItem.league_id",index并非唯一标识,数组元素顺序变化时会导致Vue复用错误的DOM节点,影响渲染性能和正确性。 - 错误处理:用
try/catch包裹API请求,避免请求失败时控制台无明确报错信息。 - 代码风格统一:async函数内直接用
await获取响应,避免混合使用then,代码逻辑更清晰。
内容的提问来源于stack exchange,提问作者Thibault
相关产品推荐
相关产品推荐

