fucai-claim/src/components/loading.ts

174 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}