数据获取
fetch、async setup、loading 状态。
30 分钟
数据获取
这一课你将能做到
- 在组件中用
fetch+ 异步加载列表,并处理 loading / error / 空数据三态 - 在
onMounted或 watch 路由参数时发起请求,并处理竞态 - 对照本站:UI 用前端框架,业务数据仍多来自 Spring Boot
/api
为什么要学
真实页面几乎都要远程数据:课程列表、用户信息、提交结果。
不会管三态,就会白屏、闪错、或显示过期列表。Vue 不绑定特定请求库——fetch 或 axios 皆可;本课用 fetch 打底。
先建立图像
进入页面 / slug 变化
→ loading=true
→ fetch /api/...
→ 成功:写入 ref;失败:error 文案
→ loading=false
模板根据三态分支渲染
| 状态 | UI |
|---|---|
| loading | 骨架/文案「加载中」 |
| error | 可重试提示 |
| success 空 | 「暂无数据」 |
| success 有 | 列表 |
跟着做
步骤 1:最小三态
<script setup>
import { ref, onMounted } from "vue";
const tracks = ref([]);
const loading = ref(false);
const error = ref("");
async function load() {
loading.value = true;
error.value = "";
try {
const res = await fetch("/api/tracks");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
tracks.value = await res.json();
} catch (e) {
error.value = e.message || "加载失败";
} finally {
loading.value = false;
}
}
onMounted(load);
</script>
<template>
<p v-if="loading">加载中…</p>
<p v-else-if="error">
{{ error }}
<button type="button" @click="load">重试</button>
</p>
<p v-else-if="tracks.length === 0">暂无课程</p>
<ul v-else>
<li v-for="t in tracks" :key="t.id || t.slug">{{ t.title }}</li>
</ul>
</template>
本地若无 /api/tracks,会走 error 分支——正好练习重试 UI。可用 JSON Placeholder 或 Vite 代理到本站后端。
步骤 2:Vite 代理(可选)
// vite.config.js
export default {
server: {
proxy: {
"/api": "http://localhost:8080",
},
},
};
指向本机 Spring Boot,与 React/Next 课 同一数据源思想。
步骤 3:随路由参数重新加载
<script setup>
import { watch } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
watch(
() => route.params.slug,
(slug) => {
if (slug) loadTrack(slug);
},
{ immediate: true }
);
</script>