feat: 添加Loading效果

This commit is contained in:
LOG1997
2025-10-12 22:30:54 +08:00
parent ebbed65253
commit 27fd0768c1
11 changed files with 266 additions and 155 deletions

View File

@@ -0,0 +1,5 @@
import type { LoadingOptions } from './loading-context'
import Loading from './index.vue'
import { loadingKey, loadingState } from './loading-context'
export { Loading, loadingKey, LoadingOptions, loadingState }

View File

@@ -0,0 +1,22 @@
<script setup lang='ts'>
import type { LoadingOptions } from './loading-context'
import { inject } from 'vue'
import { loadingKey } from './loading-context'
// 注入全局状态
const loading = inject(loadingKey) as LoadingOptions
// 解构状态(响应式)
const { visible, text } = loading
</script>
<template>
<div v-if="visible" class="fixed top-0 left-0 w-screen h-screen bg-[rgba(0,0,0,0.5)] flex flex-col gap-6 justify-center items-center z-50">
<span v-if="visible" class="loading loading-spinner loading-xl" />
<span>{{ text ? text : '加载中' }}</span>
</div>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,61 @@
// src/contexts/loading-context.ts
import type { InjectionKey, Ref } from 'vue'
import { ref } from 'vue'
// 定义 Loading 配置类型
export interface LoadingOptions {
visible: Ref<boolean>
text: Ref<string>
fullscreen: Ref<boolean>
zIndex: Ref<number>
count: Ref<number>
show: (options?: Partial<{ text: string, fullscreen: boolean, zIndex: number }>) => void
hide: () => void
}
// 注入密钥Symbol 确保唯一性)
export const loadingKey: InjectionKey<LoadingOptions> = Symbol('loading')
// 全局状态(单例)
const visible = ref(false)
const text = ref('')
const fullscreen = ref(true)
const zIndex = ref(9999)
const count = ref(0)
// 显示 Loading
function show(options?: Partial<{ text: string, fullscreen: boolean, zIndex: number }>) {
count.value++
if (count.value > 1)
return
visible.value = true
if (options) {
text.value = options.text || ''
fullscreen.value = options.fullscreen ?? true
zIndex.value = options.zIndex || 9999
}
}
// 隐藏 Loading
function hide() {
if (count.value <= 0)
return
count.value--
if (count.value === 0) {
visible.value = false
text.value = ''
fullscreen.value = true
zIndex.value = 9999
}
}
// 导出全局状态(供根组件提供)
export const loadingState: LoadingOptions = {
visible,
text,
fullscreen,
zIndex,
count,
show,
hide,
}