Admin 元件
Loading
讀取中指示。全螢幕或區塊 inline。
安裝
Terminal
pnpm dlx shadcn-vue add @admin/loadingimport { AdminLoading, vAdminLoading,} from '@/components/admin/loading'用法
<script setup lang="ts">import { ref } from 'vue'import { AdminButton } from '@/components/admin/button'import { AdminLoading } from '@/components/admin/loading'const showFullscreen = ref(false)function triggerFullscreen() { showFullscreen.value = true setTimeout(() => { showFullscreen.value = false }, 1500)}</script><template> <div class="flex flex-col items-center gap-6"> <!-- 容器內 Loading(限制在展示框內) --> <div class="relative h-32 w-64 overflow-hidden rounded-[8px] border"> <admin-loading mode="inline" /> </div> <!-- 全螢幕 Loading(1.5 秒後自動關閉) --> <admin-button variant="outline" @click="triggerFullscreen"> 觸發全螢幕 Loading(1.5s) </admin-button> <teleport to="body"> <admin-loading v-if="showFullscreen" mode="fullscreen" /> </teleport> </div></template>場景
Inline 區塊 loading
<script setup lang="ts">import { ref } from 'vue'import { vAdminLoading } from '@/components/admin/loading/v-admin-loading'const loading = ref(true)</script><template> <div class="flex flex-col gap-3"> <button class="self-start rounded-md border px-3 py-1 typo-content-medium" type="button" @click="loading = !loading" > 切換 loading </button> <div v-admin-loading="loading" class="relative h-32 w-64 rounded-md border p-4 typo-content-medium" > 被包住的內容區塊,inline mode loading 會以遮罩覆蓋此容器。 </div> </div></template>命令式全螢幕 loading
多個非同步請求共用一個全螢幕 loading:自行以 admin-loading 組裝;全域共享與計數由呼叫端決定。
下面這版用一個 ref-count counter:計數從 0 變 1 才顯示、從 1 變回 0 才隱藏,中間重疊的請求不會重複蓋上去。
<script setup lang="ts">import { ref } from 'vue'import { AdminButton } from '@/components/admin/button'import { AdminLoading } from '@/components/admin/loading'const isLoading = ref(false)let pending = 0function show() { if (pending++ === 0) { isLoading.value = true }}function hide() { if (pending > 0 && --pending === 0) { isLoading.value = false }}async function fetchData() { show() try { await new Promise((resolve) => setTimeout(resolve, 1500)) } finally { hide() }}async function fetchInParallel() { await Promise.all([fetchData(), fetchData(), fetchData()])}</script><template> <div class="flex flex-wrap gap-3"> <admin-button variant="outline" @click="fetchData"> 模擬單一請求 </admin-button> <admin-button variant="outline" @click="fetchInParallel"> 模擬三個並行請求 </admin-button> <admin-loading v-if="isLoading" mode="fullscreen" /> </div></template>想讓多個元件共用同一份 loading 狀態,把 counter 包進
createSharedComposable(@vueuse/core)就行。要不要這樣做,看你。
搭配 useOverlay
如果你已經用 useOverlay 在統一管理 overlay,也可以讓它來掛 loading。只是它的 provider 會綁 open 和 after-leave,而 admin-loading 只是純展示元件、沒有這些 emit,所以得先包一層 wrapper 幫它補上:
loading-overlay-wrapper.vue
<script setup lang="ts">import { AdminLoading } from '@/components/admin/loading'defineOptions({ name: 'loading-overlay-wrapper'})defineProps<{ open?: boolean}>()const emit = defineEmits<{ 'update:open': [value: boolean] close: [] afterLeave: []}>()</script><template> <transition enter-active-class="animate-in fade-in-0" leave-active-class="animate-out fade-out-0" appear @after-leave="emit('afterLeave')" > <admin-loading v-if="open" mode="fullscreen" /> </transition></template><script setup lang="ts">import { AdminButton } from '@/components/admin/button'import { useOverlay } from '@/components/admin/overlay'import LoadingOverlayWrapper from './loading/loading-overlay-wrapper.vue'const overlay = useOverlay()const loading = overlay.create(LoadingOverlayWrapper)let pending = 0function show() { if (pending++ === 0) { loading.open() }}function hide() { if (pending > 0 && --pending === 0) { loading.close() }}async function fetchData() { show() try { await new Promise((resolve) => setTimeout(resolve, 1500)) } finally { hide() }}async function fetchInParallel() { await Promise.all([fetchData(), fetchData(), fetchData()])}</script><template> <div class="flex flex-wrap gap-3"> <admin-button variant="outline" @click="fetchData"> 模擬單一請求 </admin-button> <admin-button variant="outline" @click="fetchInParallel"> 模擬三個並行請求 </admin-button> </div></template>API 參考
組成
<template> <admin-loading /></template>admin-loading
Props
| 名稱 | 型別 | 預設值 | 說明 |
|---|---|---|---|
mode | "fullscreen" | "inline" | undefined | — | 顯示模式變體(`fullscreen` / `inline`);未指定時預設為 `fullscreen`(fixed 全螢幕遮罩) |
label | string | undefined | "載入中" | 顯示在 spinner 旁的文字標籤 |
class | ClassValue | — | 根元素之自訂 class |
Slots
| 名稱 | Bindings | 說明 |
|---|---|---|
default | { class: string; } | — |