File size: 2,726 Bytes
89ce340 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
import { createVNode, render, type AppContext } from 'vue'
import MessageComponent from '@/components/Message.vue'
export interface MessageOptions {
type?: 'info' | 'success' | 'warning' | 'error'
title?: string
message?: string
duration?: number
closable?: boolean
ctx?: AppContext
onClose?: () => void
}
export type MessageTypeOptions = Omit<MessageOptions, 'type' | 'message'>
export interface MessageIntance {
id: string
close: () => void
}
export type MessageFn = (message: string, options?: MessageTypeOptions) => MessageIntance
export interface Message {
(options: MessageOptions): MessageIntance
info: MessageFn
success: MessageFn
error: MessageFn
warning: MessageFn
closeAll: () => void
_context?: AppContext | null
}
const instances: MessageIntance[] = []
let wrap: HTMLDivElement | null = null
let seed = 0
const defaultOptions: MessageOptions = {
duration: 3000,
}
const message: Message = (options: MessageOptions) => {
const id = 'message-' + seed++
const props = {
...defaultOptions,
...options,
id,
}
if (!wrap) {
wrap = document.createElement('div')
wrap.className = 'message-wrap'
wrap.style.cssText = `
width: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 6000;
pointer-events: none;
display: flex;
flex-direction: column;
box-sizing: border-box;
padding: 15px;
background-color: rgba(255, 255, 255, 0);
transition: all 1s ease-in-out;
align-items: center;
`
document.body.appendChild(wrap)
}
const vm = createVNode(MessageComponent, props, null)
const div = document.createElement('div')
vm.appContext = options.ctx || message._context || null
vm.props!.onClose = options.onClose
vm.props!.onDestroy = () => {
if (wrap && wrap.childNodes.length <= 1) {
wrap.remove()
wrap = null
}
render(null, div)
}
render(vm, div)
wrap.appendChild(div.firstElementChild!)
const instance = {
id,
close: () => vm?.component?.exposed?.close(),
}
instances.push(instance)
return instance
}
message.success = (msg: string, options?: MessageTypeOptions) => message({ ...options, type: 'success', message: msg })
message.info = (msg: string, options?: MessageTypeOptions) => message({ ...options, type: 'info', message: msg })
message.warning = (msg: string, options?: MessageTypeOptions) => message({ ...options, type: 'warning', message: msg })
message.error = (msg: string, options?: MessageTypeOptions) => message({ ...options, type: 'error', message: msg })
message.closeAll = function() {
for (let i = instances.length - 1; i >= 0; i--) {
instances[i].close()
}
}
export default message |