import { createApp, h } from 'vue' import Loading from './Loading.vue' // 加载组件配置接口 export interface LoadingOptions { // 加载动画类型 type?: 'spinner' | 'dots' | 'pulse' | 'ring' // 加载动画大小 size?: number | string // 加载动画颜色 color?: string // 是否全屏显示 fullscreen?: boolean // 加载文本 text?: string // 遮罩层背景色 background?: string // 遮罩层透明度 opacity?: number // 线条宽度(仅适用于spinner和ring类型) strokeWidth?: number // 线条末端样式(仅适用于spinner类型) strokeLinecap?: 'round' | 'butt' | 'square' } // Loading 实例接口 interface LoadingInstance { show: () => void hide: () => void close: () => void } // 当前活动的Loading实例 let activeInstance: LoadingInstance | null = null /** * 创建并显示一个加载组件 * @param options 加载组件配置选项 * @returns 加载组件实例,可用于手动控制显示和隐藏 */ export function showLoading(options: LoadingOptions = {}): LoadingInstance { // 如果已经有一个活动的全屏Loading实例,先隐藏它 if (activeInstance && options.fullscreen !== false) { activeInstance.hide() } // 默认配置 const defaultOptions: LoadingOptions = { type: 'spinner', size: 40, color: '#1890ff', fullscreen: true, text: '', background: 'rgba(0, 0, 0, 0.3)', opacity: 1, strokeWidth: 3, strokeLinecap: 'round' } // 合并配置 const mergedOptions = { ...defaultOptions, ...options } // 创建一个容器元素 const container = document.createElement('div') // 加载组件状态 let visible = true // 创建应用实例 const app = createApp({ render() { return h(Loading, { visible, type: mergedOptions.type, size: mergedOptions.size, color: mergedOptions.color, fullscreen: mergedOptions.fullscreen, text: mergedOptions.text, background: mergedOptions.background, opacity: mergedOptions.opacity, strokeWidth: mergedOptions.strokeWidth, strokeLinecap: mergedOptions.strokeLinecap }) } }) // 隐藏加载组件 function hideLoading() { visible = false // 卸载组件 setTimeout(() => { app.unmount() if (container.parentNode) { container.parentNode.removeChild(container) } // 如果当前实例是活动实例,清除活动实例引用 if (activeInstance === instance) { activeInstance = null } }, 300) } // 显示加载组件(默认为显示状态) function showLoadingComp() { visible = true } // 挂载组件 app.mount(container) document.body.appendChild(container) // 创建实例对象 const instance: LoadingInstance = { show: showLoadingComp, hide: hideLoading, close: hideLoading } // 如果是全屏Loading,保存为活动实例 if (mergedOptions.fullscreen) { activeInstance = instance } // 返回控制方法 return instance } /** * 隐藏当前活动的全屏加载组件 */ export function hideLoading() { if (activeInstance) { activeInstance.hide() activeInstance = null } } /** * 显示一个带有文本的全屏加载组件 * @param text 加载文本 * @param color 加载动画颜色 * @returns 加载组件实例 */ export function showLoadingWithText(text: string, color: string = '#1890ff'): LoadingInstance { return showLoading({ text, color, fullscreen: true }) } /** * 显示一个小型内联加载组件 * @param size 加载组件大小 * @param color 加载动画颜色 * @param type 加载动画类型 * @returns 加载组件实例 */ export function showInlineLoading(size: number = 24, color: string = '#1890ff', type: 'spinner' | 'dots' | 'pulse' | 'ring' = 'spinner'): LoadingInstance { return showLoading({ size, color, type, fullscreen: false }) } // 默认导出 export default { show: showLoading, hide: hideLoading, showWithText: showLoadingWithText, showInline: showInlineLoading }