You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:55:22