feat: 添加Loading效果
This commit is contained in:
5
src/components/Loading/index.ts
Normal file
5
src/components/Loading/index.ts
Normal 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 }
|
||||
22
src/components/Loading/index.vue
Normal file
22
src/components/Loading/index.vue
Normal 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>
|
||||
61
src/components/Loading/loading-context.ts
Normal file
61
src/components/Loading/loading-context.ts
Normal 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,
|
||||
}
|
||||
Reference in New Issue
Block a user