傳統的 loading 的寫法長得像底下這個樣子:
<div v-if="loading">載入中...</div>
<MyComponent v-else />
但這樣在每個需要 loading 的地方都要加上,且執行時可能會被 loading 狀態塞滿,因此可以嘗試看看 Suspense
當內部的子元件還在等待(例如資料還沒取回、元件尚未載入完成),就先顯示 fallback(備用)畫面,直到完成再顯示內容。
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<p>載入中...</p>
</template>
</Suspense>
Step1: 建立非同步元件
假設要取得 user 資料
<template>
<div class="card">
<h3>{{ user.name }}</h3>
<p>{{ user.email }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const user = ref(null)
await new Promise(resolve => setTimeout(resolve, 2000))
user.value = {
name: '小明',
email: 'ming@example.com'
}
</script>
Step2: 在父層使用 Suspense
<template>
<h2>使用者資料</h2>
<Suspense>
<template #default>
<AsyncCard />
</template>
<template #fallback>
<div>載入中,請稍候...</div>
</template>
</Suspense>
</template>
<script setup>
import AsyncCard from './AsyncCard.vue'
</script>
<script setup>
import { defineAsyncComponent } from 'vue'
const AsyncCard = defineAsyncComponent(() =>
import('./AsyncCard.vue')
)
</script>
<template>
<Suspense>
<template #default>
<AsyncCard />
</template>
<template #fallback>
<p>元件載入中...</p>
</template>
</Suspense>
</template>